Java开发技术 普通高等教育十一五 国家级规划教材 教学课件 ppt 作者 魏勇 第十章 本地方法

上传人:w****i 文档编号:94405837 上传时间:2019-08-06 格式:PDF 页数:4 大小:206.93KB
返回 下载 相关 举报
Java开发技术 普通高等教育十一五 国家级规划教材 教学课件 ppt 作者 魏勇 第十章 本地方法_第1页
第1页 / 共4页
Java开发技术 普通高等教育十一五 国家级规划教材 教学课件 ppt 作者 魏勇 第十章 本地方法_第2页
第2页 / 共4页
Java开发技术 普通高等教育十一五 国家级规划教材 教学课件 ppt 作者 魏勇 第十章 本地方法_第3页
第3页 / 共4页
Java开发技术 普通高等教育十一五 国家级规划教材 教学课件 ppt 作者 魏勇 第十章 本地方法_第4页
第4页 / 共4页
亲,该文档总共4页,全部预览完了,如果喜欢就下载吧!
资源描述

《Java开发技术 普通高等教育十一五 国家级规划教材 教学课件 ppt 作者 魏勇 第十章 本地方法》由会员分享,可在线阅读,更多相关《Java开发技术 普通高等教育十一五 国家级规划教材 教学课件 ppt 作者 魏勇 第十章 本地方法(4页珍藏版)》请在金锄头文库上搜索。

1、 318 第十章第十章 本地方法本地方法 ? 用 Java 编程语言调用一个 C 函数 用纯 Java 开发应用是理想的,但从现实上讲,有时还需用其他语言开发应用程序的一 部分。 10.1 简介简介 每一种高级语言在实际应用中总会表现出不足的地方, 所以需要借助其他高级语言的配 合。在开发 Java 的系统中,我们往往也会希望 Java 和其它语言可互相通信和调用,使它 们集成在一个应用系统中。为了满足这个要求,Sun 公司开发了 JNI(Java native Interface) 技术, JNI 是双向的, 一方面它可使运行在 JVM 中的 Java 代码调用 native 库函数或者其它

2、 程序;另一方面利用 Invocation API 将 Java 虚拟机嵌入 native 应用中。如图 10-1 所示。 JNI 异常 类 虚拟机 函数 库 应用程序 Java 端 C 端 图 10- 1 JNI 的作用 本章用于编写本地代码的语言是 C/C+,如果能访问一个捆绑 Java 和 FORTRAN 这 两种编程语言的包,也可以使用 FORTRAN 编译器编译过的代码。 我们这里之所以使用 C 语言来描述本章所讲的本地方法,因为 C 语言可能是最常用于 本地方法的语言。我们将看到如何在数据类型、功能部件名称、函数访问上使 Java 与 C 之 间保持一致(这种对应通常叫做 C 捆绑

3、)。 10.2 用用 JAVA 编程语言调用一个编程语言调用一个 C 函数函数 我们以大家偏爱的 printf 函数为例,来演示如何利用 JNI 在 Java 应用中使用 native 方 法。该 Java 程序调用 C 语言的函数来打印 Hello World!。Java 编程语言用关键字修饰本 地方法,显然,需要将 printf 函数封装到类内,因此,可以编写成如下形式的代码: public class Printf public native String printf (String s); 编译这个类后,在一个程序中使用它时,虚拟机将告诉你它不知道如何找到 printf 函数 会显示

4、一个“UnsatisfiedLinkError”错误。因此,解决的办法是给运行时间类环境提供足 够的信息,从而它能够连接这个类。在 JDK 上,需采用如下三个步骤: 319 1)为函数产生一个代码存根,它在 Java 平台调用与实际的 C 函数之间进行翻译。它从 虚拟机栈中取出参数信息并把它传给已编译的 C 函数来完成翻译过程。 2)创建一个特殊的共享库,从共享库中输出这个存根代码。 3)使用一个名为 System.loadlibrary()的特殊方法,通知 Java 运行时间环境从步骤 2 开 始装载这个库。 就像我们在前面提到的一样,首先需要在一个类中声明本地方法,native 关键字会向

5、编 译器发出警告:本地方法将在外部定义。当然,在 Java 编程语言中本地方法不包含任何代 码, 并且这种方法的标题之后会紧跟着一个终止分号, 这意味着本地方法声明与抽象方式说 明极其相似。 class HelloNative public native static void greeting(); 这个例子中, 我们将本地方法声明为静态的, 本地方法可以是静态的也可以是非静态的。 下面,编写一个相应的 C 函数,必须以 Java 运行时间环境所期望的方式准确命名这个 函数,该函数名由 Java 前缀、包名、Java 类名和 native 方法名四部分组成,各部分之间 用下划线符号分隔开,如

6、图 10-2 所示。 Java_ HelloNative_ greeting 前缀 类名 下划线 方法名 Java_HelloNative_greeting 图 10- 2 native 方法的名字组成 这里说明详细的规则: 1)使用 Java 方法名的全称,如 HelloNative.greeting。如果这个类在一个包中,那么在 方法前添上包的名称,如 com.horstmann.HelloNative.greeting。 2)用下划线替代句号,并加上前缀 Java_。例如:Java_HelloNative_greeting 或 Java_com_horstmann_HelloNative

7、_greeting。 3)如果这个类名中包含非 ASCII 字母或数字字符, 像_, 或带有u007F的 Unicode 字符用_0xxxx 来代替它们,xxxx 是 4 个十六进制位,它代表相应字符的 Unicode 值。 注意 如果为多个本地方法提供相同的名称,必须在名称后面附加两个下划线,后面 再加上编码的参数类型。例如,如果拥有本地方法 greeting()和本地方法 greeting(int repeat) , 那 么 第 一 个 称 为Java_HelloNative_greetig_, 第 二 个 则 是 Java_HelloNative_greeting_I。 如何让 Java

8、 找到本地函数 greeting 呢?为此,我们得先用 javah 来生成一个头函数。 这个实用程序能自动产生函数名称。要使用 javah 实用程序,可首先应编译源文件。 javah HelloNative 可执行的 javah 可在目录jdkbin 下找到。 例 10- 1 使用 javah 实用程序产生一头文件,HelloNative.h。 HelloNative.h /* DO NOT EDIT THIS FILE it is roachine generated */ #include /* Header for class HelloNative */ 320 # ifndef _I

9、ncluded_HelloNative # define _IncludedHe_lloNative # ifdef _cplusplus extern “C” #endif /* * class: HelloNative * Method: greeting * Signature: ()V */ JNIEXPORT void JNICALL Java_HelloNative_greeting (JNIEnv *, jclaas); # ifdef _cplusplus #endif #endif 可以看到,这个文件包含一个函数声明:Java_HelloNative_greeiing(JNI

10、EXPORT 和 JNICALL 两个字符串在头文件 jni.h 中定义。他们代表依赖于编译器的说明符,这两个说明 符用来说明源自一个动态装载库的输出函数)。 现在,你仅需将函数原型从头文件拷贝到源文件,并提供这个函数的实现代码,如例 10-2 所示。 下面根据前面的头函数,编写本地方法 例 10- 2 编写程序 HelloNative.c。 HelloNative.c #include “HelloNative.h” #include JNIEXPORT void JNICALL Java_HelloNative_greeting (JNIEnv* env, jclass cl) print

11、f ( “Hello, Native World! n”) ; 在这个简单的函数中,我们忽略了 Env 和 cl 两个参数,有兴趣的读者可以参考相关文 献。 注意 可以用 C+实现本地方法,但必须把实现本地方法的函数声明为外部 C,如: #include “HelloNative.h” #include extern “C” JNIEXPORT void JNICALL Java_HelloNative_greeting (JNIEnv* env, jclass cl) printf “Hello, Native World!n” ; 接着,编译 C 代码到一个动态装载库。在 Wlndows

12、下其有 Microsoft C+编译器,使 321 用的命令是: cl Ic:jdkinclude Ic: jdkincludewin32 -LD HelloNative.C 如果在 DOS 命令窗口中用 Visual C+编译生成 DLL,则应先运行下面的批命令: c:devstudiovcbinvcvars32.bat 以设定必要的路径和环境变量来正确配置命令行编译器。 当然, vcvars32.bat 的具体路 径可能有所不同。 最后, 我们需要添加调用 System.LoadLibrary()方法的语句以确保虚拟机在首次使用这 个类前能装载这个库。 完成这一操作的最容易方法就是在包含这

13、种本地方法的类中使用静态 初始化程序块。 HelloNative.java class HelloNative public native static void greetingo; static System.loadLibrary (“HelloNative”) ; 假定你已执行完上述所有步骤,现在就可以运行 HelloNativeTest 应用程序,测试本地 函数。 HelloNativeTest.java class HelloNativeTest public static void main(String args) HelloNative.greeting ( ); 注意在 java 源代码中,如何对本地函数命名。 当编译并运行这个程序后,”Hello,Native World!”将显在你的终端窗口上。这条信息 是由 C printf 函数生成的,而不是由 Java 编程语言代码生成的。

展开阅读全文
相关资源
相关搜索

当前位置:首页 > 高等教育 > 大学课件

电脑版 |金锄头文库版权所有
经营许可证:蜀ICP备13022795号 | 川公网安备 51140202000112号