Jni中C++和Java的参数传递

上传人:m**** 文档编号:430951682 上传时间:2022-09-24 格式:DOC 页数:12 大小:134KB
返回 下载 相关 举报
Jni中C++和Java的参数传递_第1页
第1页 / 共12页
Jni中C++和Java的参数传递_第2页
第2页 / 共12页
Jni中C++和Java的参数传递_第3页
第3页 / 共12页
Jni中C++和Java的参数传递_第4页
第4页 / 共12页
Jni中C++和Java的参数传递_第5页
第5页 / 共12页
点击查看更多>>
资源描述

《Jni中C++和Java的参数传递》由会员分享,可在线阅读,更多相关《Jni中C++和Java的参数传递(12页珍藏版)》请在金锄头文库上搜索。

1、Jni中C+和Java的参数传递 Java Native Interface(JNI)是Java语言的本地编程接口,是J2SDK的一部分。在java程序中,我们可以通过JNI实现一些用java语言不便实现的功能。通常有以下几种情况我们需要使用JNI来实现。1.标准的java类库没有提供你的应用程序所需要的功能,通常这些功能是平台相关的。2.你希望使用一些已经有的类库或者应用程序,而他们并非用java语言编写的。3.程序的某些部分对速度要求比较苛刻,你选择用汇编或者c语言来实现并在java语言中调用他们。在java核心技术中,作者提到JNI的时候,建议不到万不得已不要使用JNI技术,一方面它需要

2、你掌握更多的知识才可以驾驭,一方面使用了JNI你的程序就会丧失可移植性。在本文我们跳过JNI的底层机制,读者最好先把它想象为本地代码和java代码的粘合剂。利用VC+6.0实现JNI的最简单的例子最近项目中设计到JNI的技术,对于VC+我是一知半解.JNI是知道和Native方法的接口,从来没用过.但是摸了一会,还是感觉有点门路,搞定了JNI的难题以后,对于自己这点小小的进步不敢隐瞒,公开出来给还不了解的兄弟们作个参考. Java中使用JNI调用DLL 1编写范例文档 PublicclassTestNative Privatenativeintadd(intx, inty); Publicst

3、aticvoidmain (String args) TestNativehh=newTestNative (); intr=hh.add(30,20); System.out.println (result=+r); Static System.loadLibrary (DLL_0305); 其中LoadLibrary中的DLL文件名称可以随便定.只要做好的动态链接库改名成这个字符串就可以了.而native函数的来源就是该动态链接库.2.做好该步准备以后,用javacTestNative.java生成.class.检验语法. 3.语法检查通过以后,用javahTestNative生成.h的C

4、头文件. 4.打开VC+6.0,新建-;工程-;win32Dynamic-LinkLibrary.在向导中选择空工程. 5.把刚才javah生成的那个头文件加入工程.然后文件-;新建-;textiles自己做一个.c文件.实现自己的native函数.清单如下: #includes; JNIEXPORTjintJNICALLJava_TestNative_add(JNIEnv*ev,jobjectobj, jintx,jinty) Returnx+y; 备注: A其中的jni.h通常在jdkinclude可以先拷贝到VC安装目录下的include目录下.一劳永逸,以后可以方便使用JNI技术. B

5、全部的数据类型需要考虑Java和VC的接口问题.用jintjstring等. C函数名称和自动生成的.h文件中规定的一致.命名规则是:Java_使用类_方法名 6全编译一下工程. 如果没有出错,则此时生成动态链接库成功.把动态链接库拷贝到TestNative.java所在的目录上. 7运行javaTestNative看结果吧.在实际的使用过程中,往往需要对参数进行处理转换。才可以被C/C+程序识别。比如我们在C+中有一个结构(Struct)DiskInfo ,需要传递一个类似于DiskInfo *pDiskInfo的参数,类似于在C+这样参数如何传递到Java中呢?下面我们就来讨论C+到Jav

6、a中方法的一些常见参数的转换:定义Native Java类:如果你习惯了使用JNI,你就不会觉得它难了。既然本地方法是由其他语言实现的,它们在Java中没有函数体。但是,所有本地代码必须用本地关键词声明,成为Java类的成员。假设我们在C+中有这么一个结构,它用来描述硬盘信息: / 硬盘信息 Struct Char name 256; Int serial; DiskInfo; 那么我们需要在Java中定义一个类来与之匹配,声明可以写成这样: Class DiskInfo / 名字 Public String name; / 序列号 Public int serial; 在这个类中,申明一些N

7、ative的本地方法,来测试方法参数的传递,分别定义了一些函数,用来传递结构或者结构数组,具体定义如下面代码: /*/ /* * 定义本地方法 * */ / 输入常用的数值类型(Boolean,Byte,Char,Short,Int,Float,Double) Public native void displayParms (String showText, int i, Boolean bl); / 调用一个静态方法 Public native int add (int a, int b); / 输入一个数组 Public native void set Array (Boolean blL

8、ist); / 返回一个字符串数组 Public native String getStringArray (); / 返回一个结构 Public native DiskInfo getStruct (); / 返回一个结构数组 Public native DiskInfo getStructArray (); 编译生成C/C+头文件 定义好了Java类之后,接下来就要写本地代码。本地方法符号提供一个满足约定的头文件,使用Java工具Javah可以很容易地创建它而不用手动去创建。你对Java的class文件使用javah命令,就会为你生成一个对应的C/C+头文件。1、在控制台下进入工作路径,本

9、工程路径为:E:workjavaworkspaceJavaJni。2、运行javah 命令:Javah -classpath E:workjavaworkspaceJavaJni Com.sundy.jnidemo. ChangeMethodFromJni本文生成的C/C+头文件名为: com_sundy_jnidemo_ChangeMethodFromJni.h 在C/C+中实现本地方法生成C/C+头文件之后,你就需要写头文件对应的本地方法。注意:所有的本地方法的第一个参数都是指向JNIEnv结构的。这个结构是用来调用JNI函数的。第二个参数jclass的意义,要看方法是不是静态的(stat

10、ic)或者实例(Instance)的。前者,jclass代表一个类对象的引用,而后者是被调用的方法所属对象的引用。 返回值和参数类型根据等价约定映射到本地C/C+类型,如表JNI类型映射所示。有些类型,在本地代码中可直接使用,而其他类型只有通过JNI调用操作。使用数组JNI通过JNIEnv提供的操作Java数组的功能。它提供了两个函数:一个是操作java的简单型数组的,另一个是操作对象类型数组的。因为速度的原因,简单类型的数组作为指向本地类型的指针暴露给本地代码。因此,它们能作为常规的数组存取。这个指针是指向实际的Java数组或者Java数组的拷贝的指针。另外,数组的布置保证匹配本地类型。为了

11、存取Java简单类型的数组,你就要要使用GetXXXArrayElements函数(见表B),XXX代表了数组的类型。这个函数把Java数组看成参数,返回一个指向对应的本地类型的数组的指针。当你对数组的存取完成后,要确保调用相应的ReleaseXXXArrayElements函数,参数是对应Java数组和GetXXXArrayElements返回的指针。如果必要的话,这个释放函数会复制你做的任何变化(这样它们就反射到java数组),然后释放所有相关的资源。为了使用java对象的数组,你必须使用GetObjectArrayElement函数和SetObjectArrayElement函数,分别去

12、get,set数组的元素。GetArrayLength函数会返回数组的长度。使用对象JNI提供的另外一个功能是在本地代码中使用Java对象。通过使用合适的JNI函数,你可以创建Java对象,get、set 静态(static)和实例(instance)的域,调用静态(static)和实例(instance)函数。JNI通过ID识别域和方法,一个域或方法的ID是任何处理域和方法的函数的必须参数。表C列出了用以得到静态(static)和实例(instance)的域与方法的JNI函数。每个函数接受(作为参数)域或方法的类,它们的名称,符号和它们对应返回的jfieldID或jmethodID。如果你有

13、了一个类的实例,它就可以通过方法GetObjectClass得到,或者如果你没有这个类的实例,可以通过FindClass得到。符号是从域的类型或者方法的参数,返回值得到字符串,如表D所示。下面我们来看看,如果通过使用数组和对象,从C+中的获取到Java中的DiskInfo 类对象,并返回一个DiskInfo数组:/返回一个结构数组,返回一个硬盘信息的结构数组JNIEXPORT jobjectArray JNICALL Java_com_sundy_jnidemo_ChangeMethodFromJni_getStructArray (JNIEnv *env, jobject _obj) /申明

14、一个object数组 jobjectArray args = 0; /数组大小 jsize len = 5; /获取object所属类,一般为java/lang/Object就可以了 jclass objClass = (env)-FindClass(java/lang/Object); /新建object数组 args = (env) -NewObjectArray (len, objClass, 0); /* 下面为获取到Java中对应的实例类中的变量*/ /获取Java中的实例类 jclass objectClass = (env)-FindClass(com/sundy/jnidemo/DiskInfo); /获取类中每一个变量的定义 /名字 jfieldID str = (env) -GetFieldID(objectClass,name,Ljava/lang/String;); /序列号 jfieldID ival = (env)-GetFieldID(objectClass,serial,I); /给每一个实例的变量

展开阅读全文
相关资源
正为您匹配相似的精品文档
相关搜索

最新文档


当前位置:首页 > 机械/制造/汽车 > 工业自动化

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