Java本地调用JNI使用规范详解.doc_第1页
Java本地调用JNI使用规范详解.doc_第2页
Java本地调用JNI使用规范详解.doc_第3页
Java本地调用JNI使用规范详解.doc_第4页
Java本地调用JNI使用规范详解.doc_第5页
全文预览已结束

下载本文档

版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领

文档简介

Java本地调用JNI使用规范详解一、 JNI概述JavaNative Interface的缩写,中文为Java本地调用。从Java1.1开始,JNI即成为Java标准的一部分。JNI设计的目的是为了允许Java代码与其他语言进行交互。但这样做通常会导致丧失平台可移植性,通常是在特定的需求下进行,例如使用旧的其他语言的库、需要获得Java类库不支持的某种基于具体平台的特性、大量数学计算性能优化等。二、 JNI数据类型和数据结构1.基本类型JNI基本类型和本地等效类型的对应表格如下:Java类型本地类型说明booleanjboolean无符号,8位bytejbyte无符号,8位charjchar无符号,16位shortjshort有符号,16位intjint有符号,32位longjlong有符号,64位floatjfloat32位doublejdouble64位voidvoid无为了使用方便,还提供了如下定义:#define JNI_FALSE 0#define JNI_TRUE 1Jsize类型用于描述主要指数和大小:typedef jint jsize;2.引用类型除了基本类型外,JNI还包含了很对对应于不同Java对象的引用类型,JNI引用类型的组织层次如下图所示:在C语言中,所有其他JNI引用类型都被定义为与jobject一样,例如:typedef jobject jclass;在C+中,JNI引入虚构类以加强子类关系,例如:class _jobject;class _jstring : public jobject;typedef _jobject jobject;typedef _jstring jstring;3.方法ID和域ID方法ID和域ID是常规的C指针类型:struct_jmethodID; /*不透明结构*/typedefstruct _jmethodID *jmethodID; /*方法ID*/struct_jfieldID; /*不透明结构*/typedefstruct _jfieldID *jfieldID /*域ID*/4.值类型jvalue联合在参数数组中用作单元类型,其声明如下: typedefunion _jvalue jboolean z; jbyte b; jchar c; jshort s; jint i; jlong j; jfloat f; jdouble d; jobject l;jvalue;5.UTF8字符串JNI的UTF8字符串与标准UTF8格式有两个区别,第一,空字节0使用双字节格式进行编码,而不是标准UTF8的单字节;第二,只使用单字节、双字节和三字节格式,不支持更长的字节格式。三、 JNI接口函数命名方式1. 类型签名Java虚拟机的类型签名如下:类型签名Java类型ZbooleanBbyteCcharSshortIintJlongFfloatDdoubleLfully-qulitied-class;全限定类typetype 数组(argtypes)rettype方法类型例如,Java方法int feet(int n, String s,int arr)的类型签名如下:(ILJava/lang/String;I)I圆括号里面为参数,I表示第一个参数int型,LJava/lang/String;表示第二个参数为全限定Java.lang.String类型,I表示第三个参数为int型的数组,圆括号后面为返回值类型,I表示返回值为int型。2. 一般函数的JNI接口函数命名方式一般JNI接口函数命名如下:Java_包名_类名_方法名。例如:某工程下Sample/test包下MySigal类的int GetASample()方法的C语言实现函数命名如下:jint Java_Sample_test_MySigal_GetASample(JNIEnv* env,jobjectobj)其中,包名所包含的“/”应全部以下划线替代,其本地实现的参数和返回值也应转换为JNI类型。3. 重载函数的JNI接口函数命名方式重载函数的JNI实现在一般函数的JNI实现之外,还应添加上类型签名以作为同名函数之间的区别,其接口函数命名如下:Java_包名_类名_方法名_参数签名。例如:某工程下Sample/test包下MySigal类的int GetASample(int n, String s,int arr)方法的C语言实现函数命名如下:jintJava_Sample_test_MySigal_GetASample_ILJava_lang_String_2_3I(JNIEnv*env, jobject obj, jint n, jstring s, jintarray arr)。JNI在函数命名时采用名字扰乱方案,以保证所有的Unicode字符都能转换为有效的C函数名,所有的“/”,无论是包名中的还是全限定类名中的,均使用“_”代替,用_0,_9来代替转义字符,如下:转义字符序列表示_0XXXXUnicode字符XXXX_1字符“_”_2签名中的字符“;”_3签名中的字符“”四、 JNI函数与API在目前的应用中,我们所主要需要关心的是C/C+数据类型与JNI本地类型之间的转化过程,这个过程某些数据的转换需要使用JNIEnv对象的一系列方法来完成。1jstring转换为C风格字符串char* test = (char*)(*env)-GetStringUTFChars(env,jstring,NULL);使用完毕后,应调用:(*env)-ReleaseStringUTFChars(env,jstring, test);释放资源。2C风格字符串转换为jstringchar charStr50;jstring jstr;jstr = env -NewStringUTF(charStr);3C语言中获取的一段char*的buffer传递给Java在jni中new一个byte数组,然后使用(*env)-SetByteArrayRegion(env,bytearray, 0, len, buffer)操作将buffer拷贝到数组中。这种方式主要是针对buffer中存在“0”的情况,如果以C风格字符串的方式读入,就会损失“0”之后的字符。4数组操作数组操作的相关函数列表如下:JNI函数功能GetArrayLength返回数组中的元素数NewObjectArray创建一个指定长度的原始数据类型数组GetObjectArrayElement返回Object数组的元素SetObjectArrayElement设置Object数组的元素GetObjectArrayRegion将原始数据类型数组中的内容拷贝到预先分配好的内存缓存中SetObjectArrayRegion设置缓存中数组的值ReleaseObjectArrayRegion释放GetObjectArrayRegion分配的内存对int,char等基本数据类型的数组操作,将相关Object名称替换为对应基本数据类型名称即为相关函数。数组操作的方法选择基于使用者的需求而定,如果使用者需要在内存中拷贝数组并

温馨提示

  • 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
  • 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
  • 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
  • 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
  • 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
  • 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
  • 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。

评论

0/150

提交评论