jni讲解(理论)

整理文档很辛苦,赏杯茶钱您下走!

免费阅读已结束,点击下载阅读编辑剩下 ...

阅读已结束,您可以下载文档离线阅读编辑

资源描述

Jni理论知识讲解讲解内容Jni简介Jni设计概述Jni函数Jni类型和数据结构调用API函数1.简介Jni产生的背景什么是JniJava本地接口概述Java本地接口的方法利用Jni编程1.1jni产生的背景应用程序需要使用系统相关的功能,而Java代码不支持或是难以办到。已有其他语言写好的类库或程序,希望Java程序可以使用它们Java本地接口的方法出于更高的性能要求,希望使用汇编或是C/C++语言来实现部分功能1.2什么是JniJava本地接口(JavaNativeInterface,JNI)。JNI是本地编程接口。它使得在Java虚拟机(VM)内部运行的Java代码能够与用其它编程语言(如C、C++和汇编语言)编写的应用程序和库进行互操作从Java1.1开始,JavaNativeInterface(JNI)标准成为java平台的一部分,它允许Java代码和其他语言写的代码进行交互JNI一开始是为了本地已编译语言,尤其是C和C++而设计的,但是它并不妨碍你使用其他语言,只要调用约定受支持就可以了JAVA通过JNI调用本地方法,而本地方法是以库文件的形式存放的(在WINDOWS平台上是DLL文件形式,在UNIX机器上是SO文件形式)。通过调用本地的库文件的内部方法,使JAVA可以实现和本地机器的紧密联系,调用系统级的各接口方法1.2Java本地接口概述调用java本地方法的时机标准Java类库不支持与平台相关的应用程序所需的功能已经拥有了一个用另一种语言编写的库,而又希望通过JNI使Java代码能够访问该库想用低级语言(如汇编语言)实现一小段时限代码通过用JNI编程,可以将本地方法用于创建、检查及更新Java对象(包括数组和字符串)。调用Java方法。捕获或抛出异常。加载类和获得类信息。执行运行时类型检查。现今部分已有本地方法接口:JDK1.0本地方法接口Netscape的Java运行时接口Microsoft的原始本地接口和Java/COM接口1.4目标标准接口能够向每个用户提供以下好处每个虚拟机厂商都可以支持更多的平台相关代码工具构造器不必维护不同的本地方法接口应用程序设计人员可以只编写一种版本的平台相关代码就能够在不同的虚拟机上运行标准本地方法接口必须满足以下要求二进制兼容性效率功能1.5利用JNI编程利用JNI编程隔离了一些未知条件遵守JNI标准是本地库能在给定Java虚拟机上运行的最好保证实现JNI能确保它不会占用虚拟机实现的系统开销或施加任何限制,包括对象表示,垃圾收集机制等2.Jni设计概述JNI接口函数和指针加载和链接本地方法引用Java对象访问Java对象报告编程错误异常2.1JNI接口函数和指针含义:JNI函数可通过接口指针来获得针是指针的指针,它指向一个指针数组,而指针数组中的每个元素又指向一个接口函数每个接口函数都处在数组的某个预定偏移量中虚拟机可支持以下两个JNI函数表:一个表对非法参数进行全面检查,适用于调试程序另一个表只进行JNI规范所要求的最小程度的检查,因此效率较高2.2加载和链接本地方法解析本地方法名前缀Java_mangled全限定的类名下划线(“_”)分隔符mangled方法名对于重载的本地方法,加上两个下划线(“__”),后跟mangled参数签名如:java_(包名)_class_method字符转换转义字符序列表示_0XXXXUnicode字符XXXX。_1字符“_”_2签名中的字符“;”_3签名中的字符“[”2.3本地方法的参数第一个参数:JNI接口指针第二个参数(非静态本地方法:对象的引用、静态本地方法:其Java类的引用)其余的参数对应于通常Java方法的参数定义本地方法:packagepkg;classCls{nativedoublef(inti,Strings);...}用C实现本地方法jdoubleJava_pkg_Cls_f__ILjava_lang_String_2(JNIEnv*env,/*接口指针*/jobjectobj,/*“this”指针*/jinti,/*第一个参数*/jstrings)/*第二个参数*/{/*取得Java字符串的C版本*/constchar*str=(*env)-GetStringUTFChars(env,s,0);/*处理该字符串*/.../*至此完成对str的处理*/(*env)-ReleaseStringUTFChars(env,s,str);return...}用C++实现本地方法externC/*指定C调用约定*/jdoubleJava_pkg_Cls_f__ILjava_lang_String_2(JNIEnv*env,/*接口指针*/jobjectobj,/*“this”指针*/jinti,/*第一个参数*/jstrings)/*第二个参数*/{constchar*str=env-GetStringUTFChars(s,0);...env-ReleaseStringUTFChars(s,str);return...}2.4引用Java对象局部引用:局部引用在本地方法调用期间有效,并在本地方法返回后被自动释放掉全局引用:将一直有效,直到被显式释放实现局部应用Java虚拟机为每个从Java到本地方法的控制转换都创建了注册服务程序2.5访问Java对象访问基本类型数组Jni提供了一套函数,用于在Java数组的一部分和本地内存缓冲之间复制基本类型数组元素程序员可用另一套函数来取回数组元素的受约束版本接口提供了一些函数,用以通知虚拟机本地方法已不再需要访问这些数组元素钉住:(1)垃圾收集器必须支持钉住(2)虚拟机必须在内存中连续存放基本类型数组访问域和方法保留对所涉及类的活引用重新计算该方法ID或域ID获得方法id的方法:jmethodIDmid=env-GetMethodID(cls,f“,(ILjava/lang/String;)D);重复调用的方法:jdoubleresult=env-CallDoubleMethod(obj,mid,10,str);2.6报告编程错误强迫JNI函数去检查所有可能的错误情况将降低正常(正确)的本地方法的性能在许多情况下,没有足够的运行时的类型信息可供这种检查使用JNI不检查诸如传递NULL指针或非法参数类型之类的编程错误2.7异常异常和错误代码快速检查上一个JNI调用所返回的值以确定是否出错通过调用函数ExceptionOccurred()来获得异常对象,它含有对错误情况的更详细说明调用Java方法的JNI函数返回该Java方法的结果。程序员必须调用ExceptionOccurred()以检查在执行Java方法期间可能发生的异常某些用于访问JNI数组的函数并不返回错误代码,但可能会抛出ArrayIndexOutOfBoundsException或ArrayStoreException异步异常(在多个线程的情况下,当前线程以外的其它线程可能会抛出异步异常)该平台相关代码调用某个有可能抛出同步异常的JNI函数该平台相关代码用ExceptionOccurred()显式检查同步异常或异步异常准备数据库的驱动程序异常的处理本地方法可选择立即返回,使异常在启动该本地方法调用的Java代码中抛出平台相关代码可通过调用ExceptionClear()来清除异常,然后执行自己的异常处理代码3.jni函数函数描述NeString利用Unicode字符数组构造新的java.lang.String对象GetStringLength返回Java字符串的长度(Unicode字符数)GetStringChars返回指向字符串的Unicode字符数组的指针。该指针在调用ReleaseStringchars()前一直有效ReleaseStringChars通知虚拟机平台相关代码无需再访问chars。参数chars是一个指针,可通过GetStringChars()从string获得NewStringUTF利用UTF-8字符数组构造新java.lang.String对象GetStringUTFLength以字节为单位返回字符串的UTF-8长度GetStringUTFChars返回指向字符串的UTF-8字符数组的指针。该数组在被ReleaseStringUTFChars()释放前将一直有效ReleaseStringUTFChars通知虚拟机平台相关代码无需再访问utf。utf参数是一个指针,可利用GetStringUTFChars()从string获得字符串函数数组函数函数描述GetArrayLength返回数组中的元素数NewObjectArray构造新的数组,它将保存类elementClass中的对象。所有元素初始值均设为initialElementGetObjectArrayElement返回Object数组的元素SetObjectArrayElement设置Object数组的元素异常检查函数异常检查函数(*env)-ExceptionCheck(env)用这个函数可以检查出来是否有异常,没有返回零返回发生的异常(*env)-ExceptionOccurred(env)返回的对象会占用一个引用打印调用堆栈(*env)-ExceptionDescribe(env)清空异常(*env)-ExceptionClear(env)4.JNI的类型和数据结构基本类型和本地等效类型Java类型本地类型说明booleanjboolean无符号,8位bytejbyte无符号,8位charjchar无符号,16位shortjshort有符号,16位intjint有符号,32位longjlong有符号,64位floatjfloat32位值类型jvalue联合类型在参数数组中用作单元类型。其声明方式如下:typedefunionjvalue{jbooleanz;jbyteb;jcharc;jshorts;jinti;jlongj;jfloatf;jdoubled;jobjectl;}jvalue;类型签名类型签名Java类型ZbooleanBbyteCcharSshortIintJLongFfloatLfully-qualified-class;全限定的类[typetype[](arg-types)ret-type方法类型2.10调用API函数函数名参数返回值JNI_GetDefaultJavaVMInitArgsvm_args(指向VM-specificnitialization(特定于虚拟机的初始化)结构的指针,缺省参数填入该结构)如果所请求的版本得到支持,则返回“0”;如果所请求的版本未得到支持,则返回负数JNI_GetCreatedJavaVMsvmBuf:指向将放置虚拟机结构的缓冲区的指针。bufLen:缓冲区的长度。nVMs:指向整数的指针成功时返回“0”;失败则返回负数JNI_CreateJavaVMp_vm:指向位置(其中放置所得到的虚拟机结构)的指针。p_env:指向位置(其中放置主线程的JNI接口指针)的指针。vm_args:Java虚拟机初始化参数成功时返回“0”;失败则返回负数DestroyJavaVMvm:将销毁的Java虚拟机成功时返回“0”;失败则返回负数AttachCurrentThreadvm:当前线程所要连接到的虚拟机。p_env:指向位置(其中放置当前线程的JNI接口指针)的指针。thr_args:特定于虚拟机的线程连接参数成功时返回“0”;失败则返回负数DetachCurrentThreadvm:当前线程将断开连接的虚拟机成功时返回“0”;失败则返回负数

1 / 26
下载文档,编辑使用

©2015-2020 m.777doc.com 三七文档.

备案号:鲁ICP备2024069028号-1 客服联系 QQ:2149211541

×
保存成功