jni参数详解
从Java 1.1开始,Java Native Interface
(JNI)标准成为java平台的一部分,它允许Java代码和其他语言写的代码进行交互。JNI一开始是为了本地已编译语言,尤其是C和C++而设计的,
但是它并不妨碍你使用其他语言,只要调用约定受支持就可以了。让我们看一些使用JNI的简单例子吧。
使用java与本地已编译的代码交互,通常会丧失平台可移植性。但是,有些情况下这样做是可以接受的,甚至是必须的,比如,使用一些旧的库,
与硬件、操作系统进行交互,或者为了提高程序的性能。JNI标准至少保证本地代码能工作在任何Java 虚拟机实现下。
开始:
如果你习惯了使用JNI,你就不会觉得它难了。既然本地方法是由其他语言实现的,它们在Java中没有函数体。但是,所有本地代码必须用本地关
键词声明,成为Java类的成员。清单A演示了一个简单的类,它申明了一个本地的(native),静态的(static)方法:sum。
写完了你的Java类,接下来就要写本地代码。本地方法符号提供一个满足约定的头文件,使用Java工具可以很容易地创建它而不用手动去创建。
你对Java的class文件使用javah命令,就会为你生成一个对应的C/C++头文件。清单B就是为清单A的Test1类创建的头文件。注意:它创建了一个
C/C++函数:Java_Test1_sum。
执行本地方法:
一旦你有了这个头文件,你就需要写头文件对应的本地方法,就像我在清单C做的那样。
注意:所有的本地方法的第一个参数都是指向JNIEnv结构的。这个结构是用来调用JNI函数的,(我会在另一个章节中讨论)。第二个参数jclass的意义,
要看方法是不是静态的(static)或者实例(Instance)的。前者,jclass代表一个类对象的引用,而后者是被调用的方法所属对象的引用。最后的两个
jint参数表示了Java方法的 int参数。
返回值和参数类型根据等价约定映射到本地C/C++类型,如表A所示。有些类型,如清单B里面的两个jint参数,在本地代码中可直接使用,而其他类型
只有通过JNI调用操作。
表A
Java类型 本地类型 描述
+---------------+--------------------+--------------------------+
| boolean | jboolean | C/C++8位整型
|
| byte | jbyte | C/C++带符号的8位整型 |
| char | jchar | C/C++无符号的16位整型 |
| short | jshort | C/C++带符号的16位整型 |
| int | jint | C/C++带符号的32位整型 |
| long | jlong | C/C++带符号的64位整型 |
| float | jfloat | C/C++32位浮点型
|
| double | jdouble | C/C++64位浮点型
|
| Object | jobject
有对应 | 任何Java对象,或者没 |
| |
| 有java 类型的对象 |
| Class | jclass | Class对象
|
| String | jstring | 字符串对象
|
+---------------+--------------------+--------------------------+
|
Object[] | jobjectArray
| 任何对象的数组
|
|
boolean[] | jbooleanArray | 布尔型数组
|
|
byte[] | jbyteArray | 比特型数组
|
|
char[] | jcharArray | 字符型数组
|
|
short[] | jshortArray | 短整型数组
|
但是它并不妨碍你使用其他语言,只要调用约定受支持就可以了。让我们看一些使用JNI的简单例子吧。
使用java与本地已编译的代码交互,通常会丧失平台可移植性。但是,有些情况下这样做是可以接受的,甚至是必须的,比如,使用一些旧的库,
与硬件、操作系统进行交互,或者为了提高程序的性能。JNI标准至少保证本地代码能工作在任何Java 虚拟机实现下。
开始:
如果你习惯了使用JNI,你就不会觉得它难了。既然本地方法是由其他语言实现的,它们在Java中没有函数体。但是,所有本地代码必须用本地关
键词声明,成为Java类的成员。清单A演示了一个简单的类,它申明了一个本地的(native),静态的(static)方法:sum。
写完了你的Java类,接下来就要写本地代码。本地方法符号提供一个满足约定的头文件,使用Java工具可以很容易地创建它而不用手动去创建。
你对Java的class文件使用javah命令,就会为你生成一个对应的C/C++头文件。清单B就是为清单A的Test1类创建的头文件。注意:它创建了一个
C/C++函数:Java_Test1_sum。
执行本地方法:
一旦你有了这个头文件,你就需要写头文件对应的本地方法,就像我在清单C做的那样。
注意:所有的本地方法的第一个参数都是指向JNIEnv结构的。这个结构是用来调用JNI函数的,(我会在另一个章节中讨论)。第二个参数jclass的意义,
要看方法是不是静态的(static)或者实例(Instance)的。前者,jclass代表一个类对象的引用,而后者是被调用的方法所属对象的引用。最后的两个
jint参数表示了Java方法的 int参数。
返回值和参数类型根据等价约定映射到本地C/C++类型,如表A所示。有些类型,如清单B里面的两个jint参数,在本地代码中可直接使用,而其他类型
只有通过JNI调用操作。
表A
声明:该文观点仅代表作者本人,牛骨文系教育信息发布平台,牛骨文仅提供信息存储空间服务。
- 上一篇: java开发中前台到后台中文乱码的解决方式
- 下一篇: java程序解决中文乱码问题