Java(JNI)本地接口规范_第1页
Java(JNI)本地接口规范_第2页
Java(JNI)本地接口规范_第3页
Java(JNI)本地接口规范_第4页
Java(JNI)本地接口规范_第5页
已阅读5页,还剩107页未读 继续免费阅读

下载本文档

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

文档简介

1、JavaJava本地接口规1997年5月16日目录1.简介Java本地接口概述背景JDK1.0本地方法接口Java运行时接口原始本地接口和Java/COM接口目标Java本地接口方法利用JNI编程JDK1.1.2中的变化2.设计概述JNI接口函数和指针加载和链接本地方法解析本地方法名本地方法的参数引用Java对象全局和局部引用实现局部引用访问Java对象访问基本类型数组访问域和方法报告编程错误Java异常异常和错误代码曰J-B曰吉异少异吊异常的处理3.JNI的类型和数据结构基本类型引用类型域ID和方法ID值类型类型签名UTF-8字符串4.JNI函数接口函数表版本信息GetVersion类操作D

2、efineClassFindClassGetSuperclassIsAssignableFrom异常ThrowThrowNewExceptionOccurredExceptionDescribeExceptionClearFatalError全局及局部引用NewGlobalRefDeleteGlobalRefDeleteLocalRef对象操作AllocObjectGetObjectClassIsInstanceOfIsSameObject访问对象的域GetFieldIDGetField例程SetvtypeField例程调用实例方法GetMethodIDCallMethodCallNonvir

3、tualMethod访问静态域GetStaticFieldIDGetStaticField例程SetStaticField例程调用静态方法GetStaticMethodIDCallStaticvtypeMethod字符串操作NewStringGetStringLengthGetStringCharsReleaseStringCharsNewStringUTFGetStringUTFLengthGetStringUTFCharsReleaseStringUTFChars数组操作GetArrayLengthNewObjectArrayGetObjectArrayElementSetObjectAr

4、rayElementNewvPrimitiveTypeArray例程GetvPrimitiveTypeArrayElements例程ReleasevPrimitiveTypeArrayElements例程GetvPrimitiveTypeArrayRegion例程SetvPrimitiveTypeArrayRegion例程注册本地方法RegisterNativesUnregisterNatives监视程序操作MonitorEnterMonitorExitJava虚拟机接口GetJavaVM5.调用API概述创建虚拟机连接虚拟机卸载虚拟机初始化结构调用API函数JNIGetDefaultJava

5、VMInitArgsJNIGetCreatedJavaVMsJNICreateJavaVMDestroyJavaVMAttachCurrentThreadDetachCurrentThreadC+介绍JavaJava虚拟和汇编语言JavaNativeInterfaceJNIJNI编程接程语言C机(VM)内部运)编写的应用程行的Java序和库进行代码能够与用其它编JNI处是它没有对底层Java虚拟机的实现施加任何Java虚拟在不影响虚拟下添加对JNI的程序员只需编写一种版本的本地应用程序或库,就能够与有支持JNI的Java虚拟机协论及以下主题Java标JavaJNI编JDK1.1.2变Java尽

6、管可以完全用Java编写应用程序,但是有时单独用Java不以处理那些能满足应用程序不能完全用Java程序员使用JNI编写Java本编写应用例说明了何时需要使用Java本地方法:标准Java类库不支持与平台相关应用程序所需的功能。已经拥有了一个用另一种语言编写库,而又希望通过JNI使Java代码能够访问该库。低级语言(如汇编语言)实现一段时限代码。过JNI编程,可以创建、检查及更新Java对象(包括数组和字符串)。调用Java方法+卜AXA-H-*AXA加载类和获得类信息执行运行时类型检查以与调用API一起使用JNI,以允许任意本地应用程序嵌入到Java虚拟、ar./.这样使得程序员能够轻易地让

7、已有应用程序Java不必与虚拟机源码相链这些法库不同厂商的虚拟机提供了不同的本给定平台上编写、维护和分发多种JDK1.0本地方法接口Netscape的Java运行时Java/COMMicrosoftJDK1.0JDK1.0附带有本Java虚拟机。地方法接口。遗憾的是,有两点原因使得该接口不适合第一,平台相关码将Java对象中的域作为C结构的成员来进访问Java语言规范没有规定在内存中对象是Java拟机布局对象的方式有所不同,程序员就不不重新编译本地方法库。JDK1.0本地方法接口依赖于保unhand宏使得有必要以保守方式扫描本地堆栈。Java运行时接口Netscape建议使用Java运时(JR

8、I)Java拟机所提供服务的通JRI设计融入了可移植性-它几乎没有对底层Java虚拟机的实现细节作任何假设。JRI提出了各种各样的问题,包、调试、反射、嵌入调(原始本地接口和Java/COM接口MicrosoftJava虚拟机支持两种本地方法接口。在低一级,它提供(RNI)RNI了与JDK本地方法接口有高度源代码级们之间还进行显级MicrosoftJava/COM进Java码台相关代码必须用RNI函数来与垃圾收集为Java虚拟机提供了与语言无关的标Java对象一样来COM对Java类为COM类显给统我们认为统一的,经过细致考虑的标准接口能够向每个用户提供以下好处:每个虚拟机台相关代码。工具构造

9、器不必维护不应用程序设计人员可以只编写一种版关代码就能够在不同的虚拟机上运行获得标准本地方法联合所有对Java虚拟机有兴趣的当事方。因此,我们在Java获得许可方之间组织了一系列研讨会,对设计统一的本地方法接口进行了讨论。研讨会可标准本地方法接口必须满足以下要求:二进制兼容-主要的目标是在给所有Java虚拟机实现之间实现本地法库的二进制兼对于给定平台,程序员只需要维护一种法库。效率-若要支持时限代码,法接口必须增加一点系统开销。所有已虚拟机无关性(有二进制兼容性)的技术都会占用一定的系统开销我们必须与虚拟机无关性之间进行某种折衷。功能-接口必须显示足够的Java虚拟机内部情况以使本地方法能够完

10、务Java我们希采用一种已有的方法作为标口,因为这样程序员(程序员不得不学习拟机中的多种接口)的工作负担最轻。遗憾够完全地满足我们的目标。Netscape的JRI最接近于我们所设因而我们采用它作为设计JRI的读者将会到在API命名规则、ID似点虽。然我们进行了JNI并具有对JRI的二进制兼容性过虚拟机既JRIJNI。Microsoft的RNI是对JDK1.0的改进,因为它可以方法的问题。然RNI作与虚拟机无关的本JDK类似,RNI本地方法Java对为C结构来访问。这导问题RNI将内部Java对象的布局给了平台相关代码。Java对象作为C结构直进行访问使得屏障是高级的垃作为进标COM拟机之间的完

11、全二进制兼调COM求间接调用,而这几乎不会占系统开销。COM对象对动态链接库解本问题的方式也有很大的改进。COM作标准Java本Java/COM如访问私有Java/COM动为Java对象提供标准的IUnknown和IDispatchCOM接台相关代码能够访问公有方法和域。遗憾的是IDispatch接口不能处理重载的Java方法,方法名称时不区别小写。另外,通过IDispatchJava方执行动态类型检查和强制转换。这是因为IDispatch接口的设计只考虑到弱类型的语言(BasicCOM许软件组件(包全成熟的应起工作,而不是处单个低层函数。我们认为将所Java类或低层本地方法都当作软件组对CO

12、MUNIXCOM虽然我们没有将Java对象作为COM对象暴露给平台相关代码,JNI与COM有二进制兼容性。我们采用与COM一样的跳转表和调用约定。这意旦具有对COM,JNI就能成为Java虚拟COM我们认为JNI不应该是给定Java虚拟机所本地方法接口。标准口的好处在于程序员可台相关代码库载到不同的Java虚拟机序员可层且与虚拟有关的接口来获得较序员可层接口软件组件。实际上,们希望随着Java环境和组件软件技术发展,本地方法将变得越来利用JNI编程本地方法程序设计人员应开始利用JNI进行编程。JNI编知条件,例如终端用户可能正运行的厂商的虚拟JNI标本地库能在给定Java虚拟最好保证。例如,虽

13、然JDK1.1将继续支JDK1.0中所实现的旧式的JDK接口。依赖法将不得不重新编写如果您正在实现Java虚拟机,则应该实现JNI。们JavaSoft获许可方)尽力确保JNI不会占用虚拟机实现的系统开销或施加任何限制,包括对我们可能忽视了的问题,请告知我们。JDK1.1.2中的变化为了更好地支持Java运时环(JRE)JDK1.1.2中对调用API在几面作了扩展。这些变化没码JNI法接口也没有改变JDK1_1InitArgs结构中的reserved0域已被重新命名为version。JDK1_1InitArgs结构保存JNI_CreateJavaVM的JNI_GetDefaultJavaVMIn

14、itArgs和JNI_CreateJavaVM的调用者必须设为0 x00010001JNI_GetDefaultJavaVMInitArgs为jint持所请求的版JDK1_1InitArgs结构reserved1为properties。这NULL-终结数组。每个name=value表示系统属性(该功能对应Java中的-D选项)。在JDK1.1.1中,调DestroyJavaVM线程必须是虚拟机中的唯一用户线JDK1.1.2了这一调用DestroyJavaVM时有多个用户线程,则虚拟机将等当前线程成为唯一的用户线程,然后销毁自己-设计关。调着重讨论JNI中的主要设计问题,其中的大部分问题API设

15、计5调API讨论JNI针平台相关代码是通过调用JNI来访问Java虚拟机功能JNI可通过接口指针来获得。接口指针是指针的指针,它指向个指针数组,而指针数组中的每个元素又。每个接口函数都处数组的某个预定偏移图2-1说指针的组织结图2-1接口指针JNI接口的组织类似于C+虚拟函数表或COM接口。使用接口表编入的函数表的好处是使JNI名字空间与平台相关代码分开。虚拟地提供多个版本的JNI函数表。例如,虚拟机可支持以下两个JNI一个表对非法参数进行全面检查,适用于调试程序;另一个表只进行JNI规范所要求的最小程度的检查,因此效率较高JNI接口指针只在当线程中前线程中有效。因此,。实现JNI的虚拟机可将

16、本地线程能将接口指针从一的数据分配和储存个线程传JNI递到指针JNI接口指针当作参数来接受。虚拟机在从相同的Java线程中对本法进多次调用时,保证传递给该本地指针是相同的。但的Java线程所调用,JNI针。载和链对本地方法的加载通过System.loadLibrary方法实现。下例中,类关的本地库,在该本地库中给f的定义packagepkg;classClsnativedoublef(inti,Strings);staticSystem.loadLibrary(pkg_Cls);System.loadLibrary的序员任意选取的库名。系统按照标准的但与平台有关的处理方法将该库转换为本地库名。

17、例,Solaris系统将名称pkg_Cls转换为libpkg_Cls.soWin32系统将相同的名称pkg_Cls转换为pkg_Cls.dll程序员可用单个库来存放任意数量的类所需的所有本地方法,只要这些类将加载的本库清同的类加载器所单。提供者应该加载。虚拟机在其尽量选择能够避免内部为每个类加载器库名保护其所如果底层操作系统不支持动态链接,则必须事先法链接到拟机上。这种情况下,虚拟机实际上不需要加载库即可System.loadLibrary调员还可调用JNI函数RegisterNatives()来注册与类关联态链时RegisterNativesO别动态链接程序是根据项的名称来解析各项前缀Jav

18、a_mangled全限定的类名下划线(“_)”分隔符mangled方法名对于重载的本地方法,加上两个下划线(“_)_,”后跟mangled参数签名拟机将为本地库中的方法查找匹配的方法名。它首先查找短名(没有参数签然后再查找带参数签名的长名称。只有当载时程序员才有必要使用长名。但如果本地方,则不会有问题。因为非Java库不必用长名来链g为个方法g不是本地本地库中。classCls1intg(inti);nativeintg(doubled);我们采取简单的名字搅乱方案,以保证所有的Unicode字符C函数名。我们用下划线(“_类名中称或类字打头,我们用_0、.、_9来2-1表2-1Unicode

19、字符转换转义字符序列表示0XXXXUnicode字符XXXX。1字符“_”2签名中的字符-3签名中的字符API都要遵守给定平台上的库调用标准约使用C调用约定Win32统使用_stdcall。被转换为转义字符JNI接口指针是本地方法的第一个参静态还是非静态而有所不同。非数。其类型是静态本地方Java类的JNIEnv态本地方法的第二个参数是对其的参数对应于通常Java方法的方法调用利用调用3JNI类结将描述Java间的码2-1说如何用C函数来实现本地f对UNIX统是对对象的引用回值将结果传回类C类地方法f的声明packagepkg;classClsnativedoublef(inti,String

20、s);长mangled实现ti代码示例2-1:用C实现本地方法jdoubleJava_pkg_Cls_f_ILjava_lang_String_*env,接口指/*针*/jobjectobj,/*“this”指针*/jinti,/*第一个参数*/jstrings)第/*二个参数*/*取得Ja字符串的版本*/constchar*str=(*env)-GetStringUTFChars(env,s/*处理该字符串*/*至此完成对str的处理*/*env)-ReleaseStringUTFChars(env,s,steturn意,我们总是用接口针env2-2Java对C+此代码写得稍简洁码代码示例2

21、-2:用C+实现本地方法externC指定/*C调用约定*/jdoubleJag_Cls_f_ILjava_Stv*env,接口指/*针*/jobjectobj,/*“this”指针*/jinti,/*第一个参数*/jstrins)第/*二个参数*/constchar*str=env-GetStringUTFChars(seleaseSths(s,stetC+与C的完全应的C对应代码变得更为直接,样C+JNI针C+定义为内联成员函数,它们将扩展为Java对基本类型(Java和平台相关代码之间直接进行复制。而Java对象由引用来传递。虚拟机必须跟踪传到平台相关代码中对象,以使这些对象不会被垃圾收

22、集器释放台相关代码必须能用某种虚拟机些对象,同时,必须能够移走台相关代码引用过的对JNI将平台相关代码使用的对象引用分成两类:局部引用和法调用期间有法返回后被自动释放掉到被显式释放。对象是被作为局部引用传递给本地方JNI的所有Java对象也JNI许程序员从局部引用创建全局引用。Java对JNI函数既可接受全局引用也可接受局部引用。本地方法将局部引用或全局引用作为结果返回。大多数情况下,程序员应该依靠虚拟机在本地方法返回后释放所有局部引用。但是,有时程序员必须显式释放某个局部引用。例如,考虑以下的情形:本地方法要访问一个大型Java对象,于是创建了对该Java对象的局部引用。然后,本地方法要在返

23、回调用程序之前执行其它计算。对这个大型Java对象的局部引用将防止该对象被当作垃圾收集,即使在剩余的运算中并不再需要该对象。本地方法创建了大量的局部引用,但这些局部引用并不是要同时使用。由于虚拟机需要一定的空间来跟踪每个局部引用,创建太多的局部引用将可能使系统耗尽内存。例如,本地方法要在一个大型对象数组中循环,把取回的元素作为局部引用,并在每次如,本地方法要在一个大型对象数组中循环,把取回的元素作为局部引用,并在每次迭代时对一个元素进行操作。每次迭代后,程序员不再需要对该数组元素的局部引用。JNI允许程序员在本地方法内的任何地方对局部引用进行手工删除。为确保程序员可释JNI将不能创建额外的局部

24、引用,除非是这些JNI为结引用仅在创建它们的线程中有效引用从一个线程传递一个线程中。实现局部引用为了实现局Java拟为每Java的控制转换都创建了注册服务程序。注册服务程序将不可移动的为Java对象,并防止这些对象被当作垃圾收集。所有传给本地Java对象括那些作为JNI函数调用结果返回的对象)将被自动添加册服务程服务程序将被删除,其中的所有项都可可用各种不同的方法来实现注册服务表链、接列表或hash表来实现。虽然用计数可用来避免注册服务程复项JNI实现须检测和消除重复的项。守方式扫描本地堆栈并不能如实地实现局平台相关代码可将局部引用储存在全局或堆数据结构中。访问Java对JNI提供了一大批用来

25、访问全局数。这意味着无论虚拟机内部如何表示Java对象,相同的本地方法实现都能工作。这就是为什么JNI被各种各样的虚拟机实现所支持的关键原因。通过不透明的引用来使用访问函数的开销比直访问C结开销高。我们相信,大Java员用本地方法是为了完成一些务,此时这种接口的开销不是首要问题。访问基本类型数组对于含数据类型(如整数数组和Java对象来说,这种开销考虑一下用于执行矢量和矩阵运算的本地方法的情形便知)。对Java组进行迭代过函数调用取回数组的每个元素,决办法是引入“钉住”地方法能够要求虚拟机钉住数组内容。而后,该本值元素的直接指针。但是,这种方垃圾收集器必须支持钉住。虚拟机必须在内存中连续存放基

26、本类型数组。虽然大多数基本类型数组都是连续存放的,但布尔数组可以压缩或不压缩存储。因此,依赖于布尔数组确切存储方式的本地方法将是不可移植的。们将采取折衷方法来克服上述两个问题。先,我们提供了Java数组的一部分和本地内存缓冲之间复本类型数组元素。这些函数只有在本地方法只需访问大型数组中的一小部分元时才使用。次,程序员可用另一套函数来取回数组元素的受约束版本。记住,这些函数可求Java虚拟机分配存储空间和进行复制。虚拟机实现将决定这些函数是否真复制该数组,如如果垃圾收集器支持钉住,且数组的布局符合本地方法的要求,则不需要进行复制。否则,该数组将被复制到不可移动的内存块中(例如,复制到C堆中),并

27、进行必要的格式转换,然后返回指向该副本的指针。素。当调用这些间进行协调并将函数时,系统或副本释放。以通知虚拟机本释放数组,者在原始数组需要访问这些数组其不可移动副本这种处理可对每个给数组分别作出复制或钉住的器可能复制小对象而钉住型对象。JNI实现须确保多个线程中运可同时访问组JNI以为每个被钉住的数组保留一个内部计数器,以便某个线会解开同时被另一个线程钉组JNI必将基本类型数组锁住以专供某个本地方法访问。同时从的线程对Java数组进行更新将导致不确结果。访问JNI允许本地方法访问Java对象的域或调用其方JNI类签名来识别方法和域。从名称和签名来定域或对象的过程可分为两步。例如,为调用类cls

28、中的f方法,平台相关代码首先要获得IDjmethodIDmid=env-GetMethodID(cls,f,(ILjava/lang/String;)D);,平台相关代码可重复使用该方法ID而无须再查找该方法,如下所示:jdoubleresult=env-CallDoubleMethod(obj,mid,10,str);ID或方法ID并不能防止虚拟机卸载生成该ID的类。该类被卸载之后,该方ID或域ID亦变成无效。因此,如果平台相关代码要长时间使用某个方法ID保留对所涉及类的活引用,或重新计算该方法ID或域IDJNI对IDID实现报告编程错误JNI不检查诸如传递NULL指针或非法参数类型类的编程

29、错误。非法的参数类型包括诸如要Java类对象时却用了普通Java对象、-r这样错误JNI不检查这些编程错误的强迫JNI函数去检查所有可能的错误情况将降低正常(正确)的本地方法的性能在许多情况下,没有足够的运行时的类型信息可供这种检查使用。大多数C库函数对编程错误不进行防范。例如,printf()函地址时通常是引起运行错而不是返回错误代码。强迫C库函数检查所有可能的错误情况将有可能引起这种检查被重复进行-先是在用户代码进行,然又在库函数中再次进行员不得将非法指针或错误类型的参数传递给JNI函数。否则,可能产包括可能使系统状态受损或使虚拟机崩溃。JavaJNI允许Java处理突出的Java处理的J

30、ava传回虚拟常和错误代码JNI函数使用Java来报告错误情况。大多数情况JNI过返回错误代码并抛Java来报告错误情况。错误代码通常值(NULL这种特殊的返回值在返回值范围之外。因此,程序员快速检查上一个JNI调用所返回的值以确定是否出错,并通过调用函数ExceptionOccurred()来获得异常对象,它含有对错误情况的更详细说明。下两种情况中,程序员需要先查出异常,然后才能检查错误代码:调用Java方法的JNI函数返回该Java方法的结果。程序员必须调用ExceptionOccurred()以检查在执行Java方法期间可能发生的异常。某些用于访问JNI数组的函数并不返回错误代码,但可能

31、会抛出ArrayIndexOutOfBoundsException或ArrayStoreException。值如果不是错误代码值线程的情况影响当前线线程以外的其它线程可能会抛出异步相关代码的执行,直到出现下列情况该平台相关代码调用某个有可能抛出同步异常的JNI函数,或者该平台相关代码用ExceptionOccurred()显式检查同步异常或异步异常注意,只有那些有可能抛出同步异常的JNI函数才检查异步异常。本地方法应在必要的地方(例如,它异常检查的紧密循环ExceptionOccurred()检查以确保当前线程可在适当时间内对异步异应。的处理种方法来处理平台相关代码本地方法可选择立即返回,使异

32、常在启动该本地方法调用的Java代码中抛出。平台相关代码可通过调用ExceptionClear()来清除异常,然后执行自己的异常处理代码。JNI关代码必须先以下这些JNIIDIDIDID为义调试-JNI的类型和数据结讨论JNI如何将Java类型映射到本地C类3TJava类计关类表3-1基本类型和本地等效类型Java类型本地类型说明booleanjboolean无符号,8位bytejbyte无符号,8位charjchar无符号,16位shortjshort有符号,16位intjint有符号,32位longjlong有符号,64位floatjfloat32位doublejdouble64位void

33、voidN/A、丄/.jsize整数类型用于描述主typedefjintjsize;IDIDIDID为义IDIDIDID为义JNI对应Java类JNI组织层IDIDIDID为义图3-1IDIDIDID为义IDIDIDID为义jobieirt尸尸有Java;ic1assjs11iflqjattayjobj已匚七Attayjboq1已吕nArrayjbyt已AtEmyjchatAttayjshortArtayjintArtayjlodqAttsyj1oat.Artayjdoub1已卫!工Ttayjthrowabl已JNIjamlan月.das号応敷;java.Ian月.Strin月对敏;(数组to

34、bject黑鱼Fl;fbooleanfit组CbyteftSa)晶r迪绡:shortfill组tintftifi)血n月教组IflORt数组dou血数组;jaiTLlaTL月.Thrciivaljle对象;3-1引用类型层次义为与jobject一样IDIDIDID为义IDIDIDID为义typedefjobjectjclass;C+JNI类关IDIDIDID为义IDIDIDID为义class_jobject;class_jclass:public_jobject;typedef_jobject*jobject;typedef_jclass*jclass;为义IDID规的C指针类不透明结构域不透

35、明结构方法为义为义值类联类组单类类型签JNIJava拟类签3-2这类签表3-2Java虚拟机类型签名类型签名Java类型Zbooleanbyte值为(x&0 x1f)6)+(y&0 x3f)节值为(x&0 x1f)6)+(y&0 x3f)节为义CcharSshortIintJlongFfloatDdoubleLfully-qualified-class;全限定的类typetype(arg-types)ret-type方法类型,Java方法:longf(intn,Strings,intarr);以下类型签名:(ILjava/lang/String;I)JUTF-8值为(x&0 x1f)6)+(y

36、&0 x3f)节值为(x&0 x1f)6)+(y&0 x3f)节为义值为(x&0 x1f)6)+(y&0 x3f)节值为(x&0 x1f)6)+(y&0 x3f)节为义JNI用UTF-8字符串来表示各种字符类UTF-8样UTF-8符串的编码方仅ASCII够按每字符一个字节表16u007F范围内的字符都用单字节表示00-6位节的值。空(u000)xyJava虚拟机所u0001u0080uO7FF1106-10位围内的字符用一对字节10位为义x,yu0800到uFFFF范围为义为义|d|l215位7:|110S-11位为义为义值为(x&0 xf)12)+(y&0 x3f)类型必须为void(V)。

37、clazz参数务必不要引组类NewObject编程人员应将传递给构数紧跟着放在methodIDNewObject()收到这些们传给编程人员所要调用的Java方法。NewObjectA编程人员应将传递给构造函数的所有参数放在jvalues类型的数组args中,该数组紧跟着放在methodID参数NewObjectO组这将把它们传给编程人员所要调用Java为义NewObjectVva_list类NewObject()收到这args该后,将把它们编程人员应将传递给构造函数的参数紧跟着放在methodID参数传给编程人员所要调用的Java参数:env:JNI接口指针。clazz:Java类对象。met

38、hodIDIDNewObject的其它参数:传给构造函数的参数。NewObjectA的其它参数:args传给组NewObjectV的其它参数:args传给va_list返回值:返回Java对象,如果无法构造该对象,则返回NULL抛出:InstantiationException该类为类OutOfMemoryError为义GetObjectClass返回对象的类。参数:env:JNI接口指针ob:Jjava对象(不返回值:返回Java类对象IsInstanceOf类的实测试对象是否为某参数:env:JNI接口指针ob:Jjava对象。cla:Jzazva类对象返回值:可将强转换为对象可强制转换为

39、任何类。GetFieldID()类GetFieldID()类为义IsSameObjectjbooleanIsSameObject(JNIEnv*env,jobjectref1,jobjectref2);测试两个引用是否引用同一Java对象。参数:env:JNI接口指针。ref1:Java对象。ref2:Java对象。返回值:reflref2Java对为NULL则JNI_TRUE则回JNI_FALSE。访问对GetFieldIDjfieldIDGetFieldID(JNIEnv*env,jclassclazzconstchar*name,constchar*sig);类实态ID该签名指定。访问G

40、etFieldID()类GetFieldID()类为义GetFieldSetFieldID检对GetFieldID()获取数组的长应使用GetArrayLength()GetFieldID()获取数组的长应使用GetArrayLength()为义参数:env:JNI接口指针。clazz:Java类对象。name:0终结的UTF-8字符串中的域名。sig:0终结的UTF-8字符串中的域签名。返回值:ID败则NULL抛出:NoSuchFieldErrorExceptionlnlnitializerError导类败OutOfMemoryError统GettypeFieldNativeTypeGetF

41、ield(JNlEnv*env,jobjectobjjfieldlDfieldlD);该访问对象的实态)域的值。要访问过调GetFieldID()获取数组的长应使用GetArrayLength()GetFieldID()获取数组的长应使用GetArrayLength()为义结类应GettypeFieldtype实际NativeType换GetFieldlD()而得到的域ID下表说明了GetField替换为域的Java类型(或为该例程对应的本地类型。为义表4-1GetField访问器例程系列GetField例程名本地类型GetObjectField()jobjectGetBooleanField

42、()jbooleanGetByteField()jbyteGetCharField()jcharGetShortField()jshortGetIntField()jintGetLongField()jlongGetFloatField()jfloatGetDoubleField()jdouble参数:env:JNI接口指针。obj:Java对象(不能为NULLfieldIDID返回值:SettypeFieldvoidSetField(JNIEnv*env,jobjectobj,jfieldIDfieldID,NativeTypevalue);ID该访问器例程系列设置对象的实例(非静态)域的值

43、。要访问的域由通过调SetFieldID()为义说SetField结类应SetFieldtype换为Java类实际NativeType换为该例程对应的本地类型。表4-2SetField访问器例程系列SetField例程名本地类型SetObjectField()jobjectSetBooleanField()jbooleanSetByteField()jbyteSetCharField()jcharSetShortField()jshortSetIntField()jintSetLongField()jlongSetFloatField()jfloatSetDoubleField()jdoubl

44、e参数:env:JNI接口指针。obj:Java对象(不为NULLfieldIDID。value值调用实GetMethodID为义jmethodIDGetMethodID(JNIEnv*env,jclassclazzconstchar*name,constchar*sig);类实态IDclazz类义为义clazz继该签GetMethodID()ID应init为时void(V)为参数:env:JNI接口指针。clazz:Java类对象。name:0终结的UTF-8字符串中的方法名。sig:0终结的UTF-8字符串中的方法签名返回值:ID则为NULL抛出:NoSuchMethodErrorExce

45、ptionlnlnitializerError导类OutOfMemoryErrorCallMethod例CallMethodA例CallMethodV例NativeTypeCallMethod(NativeTypeCallMethodA(NativeTypeCallMethodV(这三个调Java实。它们的差别仅在于向所调用的方法传递参数时所用的这三个ID调用Java对象的实例(非静态)方法。须过调获当这些函数用于调用私时ID须实类而不应从其某个超类派生CallMethod例程编程人员应将要传给方紧CallMethod接受这些参数并将其传给编程人员所要调JavaCallMethodA例程编程人

46、员应将要传给方法的所有参数放在紧跟在类型数组argsCallMethodAroutine受这些数组中的参并将其传给编程人员所要调用的Java方法。为义CallMethodV例程编程人员紧跟着在methodIDva_list类变CallMethodVroutine这传给编程人员调Java结果类型说调用例程。用户应将CallMethodtype替换为所调用方法的Java类同时为义NativeType换为该表4-3实例方法调用例程CallMethod例程名本地类型为义为义voidCallVoidMethod()CallVoidMethodA()CallVoidMethodV()CallObjectM

47、ethod()CallObjectMethodA()CallObjectMethodV()jobjectCallBooleanMethod()CallBooleanMethodA()CallBooleanMethodV()CallByteMethod()CallByteMethodA()CallByteMethodV()jbyteCallCharMethod()CallCharMethodA()CallCharMethodV()jcharCallShortMethod()CallShortMethodA()CallShortMethodV()jshortCallIntMethod()CallI

48、ntMethodA()CallIntMethodV()jintCallLongMethod()CallLongMethodA()CallLongMethodV()jlongCallFloatMethod()CallFloatMethodA()CallFloatMethodV()jfloatCallDoubleMethod()CallDoubleMethodA()CallDoubleMethodV()jdouble参数:env:JNI接口指针obj:Java对象。methodIDIDCallMethod例程的其它参数:传给JavaCallMethodA例程的其它参数:组CallMethodV例程

49、的其它参数:va_list返回值:调Java结抛出:执行Java方法时抛出的异常。CallNonvirtualMethod例程CallNonvirtualMethodA例程CallNonvirtualMethodV例程NativeTypeCallNonvirtualMetho(dJNIEnv*env,jobjNativeTypeCallNonvirtualMethod(AJNIEnv*env,jobNativeTypeCallNonvirtualMethod(VJNIEnv*env,job这些操作根据指定的类和方法ID调用某Java对象的实例(非静态)方法。参须过调类的获CallNonvirt

50、ualMethodCallMethodCallMethod对类调CallNonvirtualMethod为义则根据获真实类或IDclazz类获类调ID须对CallNonvirtualMethod例程编程人员应将要传给紧methodIDCallNonvirtualMethodroutine接受这传给编程人员所要调JavaCallNonvirtualMethodA例程编程人员应将要传给紧跟在methodIDjvalues类型数组argsCallNonvirtualMethodAroutine这些数组传给编程人员所要调用的Java编程人员应将要传给方法的所有参数放在紧跟在methodID参数之后的v

51、a_list类型数argsCallNonvirtualMethodVToutine这将其传给编程人员所要调用的JavaCallNonvirtualMethodV例程调用例程。用户应下表根据结果类型说明了各CallNonvirtualMethod表中的实际方法调用例程名type替换为所调用方法的Java类时NativeType换为该应表4-4CallNonvirtualMethod例程CallNonvirtualMethod例程名本地类型CallNonvirtualVoidMethod()CallNonvirtualVoidMethodA()CallNonvirtualVoidMethodV()

52、CallNonvirtualObjectMethod()CallNonvirtualObjectMethodA()CallNonvirtualObjectMethodV()CallNonvirtualBooleanMethod()CallNonvirtualBooleanMethodA()jboolean为义jbytejcharjshortjintjlongjfloatjdouble参数:env:JNI接口指针。cla:zJzava类。ob:jJava对象。IDCallNonvirtualMethod例程的其它参数:传给JavaCallNonvirtualMethodA例程的其它参数:组Cal

53、lNonvirtualMethodV例程的其它参数:ID态域,则为NULLID态域,则为NULL为义签GetStaticFieldID检态类初始化。静态签名返回值:调用Java方法的结果抛出:执行Java方法时访问静态GetStaticFieldIDjfieldIDGetStaticFieldID(JNIEnv*env,jclassclazzconstchar*name,constchar*sig);返回类的静态域的域ID。SetStaticField访问GetStaticFieldID()将未参数:env:JNI接口指针。clazz:Java类对象。name:0终结的UTF-8sig:0终结

54、的UTF-8字符返回值:抛出:抛出:为义导致类初始化程序失败NoSuchFieldErrorExceptionInInitializerErrorOutOfMemoryError统GetStaticFieldNativeTypeGetStaticField(JNIEnv*env,jclassclazzjfieldIDfieldID);过调该访问器例程系列返回对象的静态域的值。要访问GetStaticFieldID()而得到的域ID指定。抛出:抛出:为义抛出:抛出:为义说明了GetStaticField中的type替换为域的Java类NativeType换为该对应结果类型。应将GetStatic

55、Field表中的某个实际例程名),然后将抛出:抛出:为义抛出:抛出:为义表4-5GetStaticField访问器例程系列GetStaticField例程名本地类型GetStaticObjectField()jobjectGetStaticBooleanField()jbooleanGetStaticByteField()jbyteGetStaticCharField()jcharGetStaticShortField()jshortGetStaticIntField()jintGetStaticLongField()jlongGetStaticFloatField()jfloat为义jdou

56、bleGetStaticDoubleField()参数:env:JNI接口指针。clazz:Java类对象。fieldID态ID返回值:态SetStaticField例程voidSetStaticFiel(dJNIEnv*env,jclassclazz,jfieldIDfieldID,NativeTypevalue);该访问器例程系列设置对象的静态域的值。要访问的域由通过调用GetStaticFieldID()而得到的域ID指定。说SetStaticField结类应SetStaticField中的type替换为域的Java类型(或使用表中的某个实际例程名),然后将NativeType换为该对应

57、类表4-6SetStaticField访问器例程系列SetStaticField例程名本地类型SetStaticObjectField()jobjectSetStaticBooleanField()jbooleanSetStaticByteField()jbyteSetStaticCharField()jcharSetStaticShortField()jshortSetStaticIntField()jintSetStaticLongField()jlongjfloatjdoubleSetStaticFloatField()SetStaticDoubleField()参数:env:JNI接口

58、指针。clazz:Java类对象。fieldID态IDvalue值调用静态方法GetStaticMethodIDjmethodIDGetStaticMethodID(JNIEnv*env,jclassclazzconstchar*name,constchar*sig);返回类的静态方法的方法ID。方法由其名称和签名指定。GetStaticMethodID()将未初始化的类初始化。参数:env:JNI接口指针clazz:Java类对象name:0终结UTF-8字符串中静态方法名。sig:0终结UTF-8字符串中的方法签名。返回值:返回值:ID必须从clazz类ID必须从clazz类为义ID败则为

59、NULL抛出:TOC o 1-5 h z HYPERLINK l bookmark178NoSuchMethodError态 HYPERLINK l bookmark180ExceptionlnlnitializerError导类败 HYPERLINK l bookmark182OutOfMemoryError统CallStaticMethod例程CallStaticMethodA例程CallStaticMethodV例程NativeTypeCallStaticMetho(dJNlEnv*env,jclassclazz,jmethodlDmethodlD,.);NativeTypeCallSt

60、aticMethodA(JNlEnv*env,jclassclazz,jmethodlDmethodlD,jvalue*args);NativeTypeCallStaticMethodV(JNlEnv*env,jclassclazz,jmethodlDmethodlD,va_listargs);这ID调Java对态methodID须通过调用GetStaticMethodlD()得到。为义CallStaticMethod例程编程人员应将要传给紧跟着放在methodID为义传给编程人员所要调CallStaticMethodroutine接受这表4-7CallStaticMethod调用例程Call

温馨提示

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

评论

0/150

提交评论