JavaJNI调用的完全手册

上传人:M****1 文档编号:471808620 上传时间:2023-12-24 格式:DOC 页数:156 大小:439.50KB
返回 下载 相关 举报
JavaJNI调用的完全手册_第1页
第1页 / 共156页
JavaJNI调用的完全手册_第2页
第2页 / 共156页
JavaJNI调用的完全手册_第3页
第3页 / 共156页
JavaJNI调用的完全手册_第4页
第4页 / 共156页
JavaJNI调用的完全手册_第5页
第5页 / 共156页
点击查看更多>>
资源描述

《JavaJNI调用的完全手册》由会员分享,可在线阅读,更多相关《JavaJNI调用的完全手册(156页珍藏版)》请在金锄头文库上搜索。

1、JNI调用的注意事项2JNI系统一些细节点总结3Java和C之间互相传递字符串7Java和C互操作的异常问题处理9Java与CC+之间通过JNI传递中文字符串9Java: JNI完全手册17JNI使用技巧点滴(二)23JNI部分24Tomcat+jsp+javaBean的例子26JNI调用固有方法30Java基础知识JNI入门介绍(下)32Java调用本地方法(JNI浅谈)38使用JNI的步骤44JAVA与C+:关于JNI中文字符串操作问题总结47Windows 平台上实现 Java 本地方法实用的示例、步骤和准则51例解 VC+ 6.0 实现 JNI58JNI中文处理问题小结63jni的中文

2、字符串处理72JNI中jstring类型与c语言中的字符串的转换74jstring和char*之间的转换方法76用Delphi开发JNI(Java Native Interface)应用(一)77java通过JNI与delphi交互80使用JNI技术实现JAVA程序调用dll83HP-UX下使用JNI访问标准C+程序89 / JNI调用的注意事项JNI的简单教程网上很多,看看就能够明白,照着操作也基本能够做下来。但是因为大多的教程写的都不够详细,在照着操作时候可能会遇到几个小问题,故开篇时在这里简单总结一下。1. 在C语言环境中编译代码,出现编译错误,类型为找不到jni.h文件。解决方法:在j

3、dk中寻找到jni.h和jni_md.h文件,将这两个文件拷贝到C语言编译器的include目录中。具体的目录可能会跟编译器有关。比如Dev C+中,将其直接拷贝到include目录下即可。2. 在C语言环境中编译代码,出现编译错误,类型为参数错误。解决方法:不能简单的把生成的.h文件中的方法名直接拷贝到.c文件中去,需要加入具体的参数。例如JNIEXPORT void JNICALL Java_testdll (JNIEnv *, jclass, jint)应该更改为JNIEXPORT void JNICALL Java_testdll (JNIEnv * para1, jclass, ji

4、nt para2)。3. 在Java中调用JNI时候,java.lang.UnsatisfiedLinkError错误发生。解决方法:生成的dll文件放错了位置,所以不能加载dll文件。试试将dll文件放在与class文件同一目录,再试试放在package的根目录。1、建的dll工程里一定要是.c文件。2、一定要是release编译的dll文件,不要用debug生成的。3、javah 时使用完整包名.类名 (重要!)编译举例:调用JNI的Java源文件FpMatch.java 。package com.until.tc;public class FpMatch public static na

5、tive int FpMatch_TESO(String szReg, String szVer, int nLevel);public FpMatch() /* 载入动态库 */static try System.loadLibrary(FpMatch_TESO_JNI); catch (Exception e) e.printStackTrace();编译说明:javac -d ./ FpMatch.java -d ./ 参数会在当前目录下,依次建立package指定的目录,并把FpMatch.class放在package指定路径下,为下一步的javah做准备。javah -d ./ co

6、m.until.tc.FpMatch 增加-d参数才可以生成正确的.h文件。这样JNI调用函数名里才包括了package的路径。JNI系统一些细节点总结一系统环境 2二JNI的简要使用例子 2三JNI调用中考虑的问题 3四JNI中对JAVA传入数据的处理 5五JAVA调用本地接口后的数据处理问题 5六JAVA中的一些小东西 5一系统环境linux操作系统kernel2.4.2,安装j2sdk1.4.0二JNI的简要使用例子下面是一个简单的例子实现打印一句话的功能,但是用的c的printf最终实现。一般提供给java的jni接口包括一个so文件(封装了c函数的实现)和一个java文件(需要调用p

7、ath的类)。1 JNI的目的是使java方法中能够调用c实现的一些函数,比如以下的java类,就需要调用一个本地函数testjni(一般声明为private native类型),首先需要创建文件weiqiong.java,内容如下:class weiqiongstaticSystem.loadLibrary(testjni);/载入静态库,test函数在其中实现private native void testjni(); /声明本地调用public void test()testjni();public static void main(String args)weiqiong haha =

8、 new weiqiong();haha.test();2然后执行javac weiqiong.java,如果没有报错,会生成一个weiqiong.class。3然后执行javah weiqiong,会生成一个文件weiqiong.h文件,其中有一个函数的声明如下:JNIEXPORT void JNICALL Java_weiqiong_testjni(JNIEnv *, jobject);4创建文件testjni.c将上面那个函数实现,内容如下:#include #include JNIEXPORT void JNICALL Java_weiqiong_testjni(JNIEnv *env

9、, jobject obj)printf(haha-go into c!n);5为了生成.so文件,创建makefile文件如下:libtestjni.so:testjni.o makefilegcc -Wall -rdynamic -shared -o libtestjni.so testjni.otestjni.o:testjni.c weiqiong.hgcc -Wall -c testjni.c -I./ -I/usr/java/j2sdk1.4.0/include -I/usr/java/j2sdk1.4.0/include/linuxcl:rm -rf *.o *.so注意:gcc

10、前面是tab空,j2sdk的目录根据自己装的j2sdk的具体版本来写,生成的so文件的名字必须是loadLibrary的参数名前加“lib”。6export LD_LIBRARY_PATH=.,由此设置library路径为当前目录,这样java文件才能找到so文件。一般的做法是将so文件copy到本机的LD_LIBRARY_PATH目录下。7执行java weiqiong,打印出结果:“haha-go into c!”三JNI调用中考虑的问题在首次使用JNI的时候有些疑问,后来在使用中一一解决,下面就是这些问题的备忘:1。 java和c是如何互通的?其实不能互通的原因主要是数据类型的问题,jn

11、i解决了这个问题,例如那个c文件中的jstring数据类型就是java传入的String对象,经过jni函数的转化就能成为c的char*。对应数据类型关系如下表:Java 类型 本地c类型 说明boolean jboolean 无符号,8 位byte jbyte 无符号,8 位char jchar 无符号,16 位short jshort 有符号,16 位int jint 有符号,32 位long jlong 有符号,64 位float jfloat 32 位double jdouble 64 位void void N/AJNI 还包含了很多对应于不同 Java 对象的引用类型如下图:2。 如

12、何将java传入的String参数转换为c的char*,然后使用?java 传入的String参数,在c文件中被jni转换为jstring的数据类型,在c文件中声明char* test,然后test = (char*)(*env)-GetStringUTFChars(env, jstring, NULL);注意:test使用完后,通知虚拟机平台相关代码无需再访问:(*env)-ReleaseStringUTFChars(env, jstring, test);3. 将c中获取的一个char*的buffer传递给java?这个char*如果是一般的字符串的话,作为string传回去就可以了。如果

13、是含有 的buffer,最好作为bytearray传出,因为可以制定copy的length,如果copy到string,可能到 就截断了。有两种方式传递得到的数据:一种是在jni中直接new一个byte数组,然后调用函数(*env)-SetByteArrayRegion(env, bytearray, 0, len, buffer);将buffer的值copy到bytearray中,函数直接return bytearray就可以了。一种是return错误号,数据作为参数传出,但是java的基本数据类型是传值,对象是传递的引用,所以将这个需要传出的byte数组用某个类包一下,如下:class R

14、etObjpublic byte bytearray;这个对象作为函数的参数retobj传出,通过如下函数将retobj中的byte数组赋值便于传出。代码如下:jclass cls;jfieldID fid;jbyteArray bytearray;bytearray = (*env)-NewByteArray(env,len);(*env)-SetByteArrayRegion(env, bytearray, 0, len, buffer);cls = (*env)-GetObjectClass(env, retobj);fid = (*env)-GetFieldID(env, cls, retbytes, B);(*env)-SetObjectField(env, retobj, fid, bytearray);4。 不知道占用多少空间的buffer,如何传递出去呢?在jni的c文件中new出空间,传递出去。java的数据不初始化,指向传递出去的空间即可。四JNI中对JAVA传入数据的处理1 如果传入的是bytearray的话,作如下处理得到buffer:char *tmpdata = (char*)(*env)-GetByteArrayElements(env, bytearray, N

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

最新文档


当前位置:首页 > 医学/心理学 > 基础医学

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