Java通过JNI与C/C++进行相互调用

1002937751 贡献于2013-01-29

作者 张文全  创建于2013-01-29 05:55:37   修改者  修改于1899-12-30 00:00:00字数2978

文档摘要:最近在做关于javac之间相互调用的问题,搜索了一些资料,进行了一些整理,希望可以和大家一起分享学习,共同进步。第一步编写Java类首先,我们创建一个名为test的Eclipse工程,并新建一个src源代码目录,testdll的package这里我们编写一个Java类,命名为HelloWorld,HelloWorld类包含一个本地方法。
关键词:

Java 通过JNI与C/C++进行相互调用 最近在做关于java c之间相互调用的问题,搜索了一些资料,进行了一些整理,希望可以和大家一起分享学习,共同进步。 第一步 编写Java类 首先,我们创建一个名为test的Eclipse工程,并新建一个src源代码目录,testdll的package这里我们编写一个Java类,命名为HelloWorld,HelloWorld类包含一个本地方法displayHelloWorld(),HelloWorld的源码清单如下: HelloWorld.java源码: public class HelloWorld { public native void displayHelloWorld();① static{ System.loadLibrary("HelloWorld"); ② } public static void main(String[] args){ HelloWorld helloWorld = new HelloWorld(); helloWorld.displayHelloWorld(); } } 说明:①是java本地方法申明;②装入动态链接库,"HelloWorld"是要装入的动态链接库名称。 第二步 编译Java类 在Eclipse工具中编译Java类。编译后的class文件会自动放入工程目录下的bin目录中。 Java 文件保存的时候eclipse自动进行编译。 第三步 生成C/C++头文件 在 windows中打开一个命令窗口(cmd),进入test项目工程所在目录 D:\zhang_wenquan\workspace编译生成.h文件。 具体操作:进入test工程所在的目录D:\zhang_wenquan\workspace\test\src D:\zhang_wenquan\workspace\test\src>javah -classpath D:\zhang_wenquan\workspace\test\bin testdll.HelloWorld 按回车即可 生成的.h 文件在D:\zhang_wenquan\workspace\test\src目录下,文件名称为:testdll_HelloWorld.h 第四步 编写本地方法实现 1) 用VC6创建HelloWorld Win32动态链接库工程。将上述生成的头文件testdll_HelloWorld.h拷贝到E:\VCgreen\MyProjects目录下面。(E:\VCgreen\MyProjects为我工程的目录) 2) 将 C:\Program Files\Java\jdk1.6.0_10\include目录下的jni.h和C:\Program Files\Java\jdk1.6.0_10\include\win32\jni_md.h两个头文件 拷贝到VC安装目录下面的E:\VCgreen\VC98\Include中。(VC在本机上的安装目录为E:\VCgreen\VC98) 3)在VC IDE中新建HelloWorld.cpp文件,实现头文件中声明的方法并编译生成DLL。 HelloWorld.cpp源码 #include "testdll_HelloWorld.h" #include main { return true; } /* * Class: HelloWorld * Method: displayHelloWorld * Signature: ()V */ JNIEXPORT void JNICALL Java_testdll_HelloWorld_displayHelloWorld (JNIEnv *, jobject) { printf("Hello World!This is java call me \n"); int sum=0; int i; for(i=0;i<10;i++) { sum=sum+i; } printf("sum= %d\n",sum); } 点击Build(F7)生成HelloWorld.dll文件 (DLL生成的路径为E:\VCgreen\MyProjects\HelloWorld\Debug\...) 第五部 运行测试程序 要运行Java 必须要能够让java加载c/c++生成的那个.dll文件,本例中就是HelloWorld.dll 实现方式有两种: (1)直接将dll拷贝到C:\WINDOWS\system32下面(实现)。有局限性,这种方式只能适用于wingdows操作系统,并且每生成一个dll文件都要进行复制粘贴的工作,比较繁琐。 (2)将工程生成的dll文件夹加入到系统的环境变量中去,这样java在运行的时候就可以轻松的找到dll文件了。 环境变量的设置方法: 右击我的电脑—〉属性—〉高级系统设置—〉点击环境变量。出现如图所示的界面。 选中Path进行编辑 把E:\VCgreen\MyProjects\HelloWorld\Debug这个目录加入到path里,点击确定。这样系统的环境变量就设置好了。最后重启eclipse. 方式2 不需要进行复制dll文件,程序在运行的时候能够直接找到dl文件,比较方便。建议使用方式2。 运行结果: 运行HelloWorld.java程序,将看到控制台输出结果为: Hello World!This is java call me sum=45 第六:中间可能遇到的问题 如果报错的话可能是java.lang.UnsatisfiedLinkError: no Hello in java.library.path,说明在System.loadLibrary("Hello");写的动态库名字不正确,系统找不到,这里应该是HelloWorld。 如果名字写的正确的但还是报这个错误说明是HelloWorl.dll文件的位置放的不正确,要确定是在工程的bin目录上或许是C:\WINDOWS\system32下才可以正确运行 cpp文件中JNIEXPORT void JNICALL Java_testdll_HelloWorld_displayHelloWorld中JNICALL是关键字,Java_testdll_HelloWorld_displayHelloWorld中java到displayHelloWorld中间是类的路径,displayHelloWorld是方法名,中间要加上包名的全部路径。这样在HelloWorld的方法中声明的native方法名应该是displayHelloWorld(),如果执行的时候报错是: Exception in thread "main" java.lang.UnsatisfiedLinkError: testdll.HelloWorld.HelloWorld_displayHelloWorld()V,是因为HelloWorld.java的native方法名跟dll中的名字不一致,错误是因为dll中最后的方法名是displayHelloWorld,而HelloWorld.java中方法名声明成了HelloWorld_displayHelloWorld。改成一致的就可以执行成功了。 参考资料: http://hi.baidu.com/yanhongyan1987/item/094c820c237dce8903ce1b46 http://www.iteye.com/topic/295776

下载文档到电脑,查找使用更方便

文档的实际排版效果,会与网站的显示效果略有不同!!

需要 7 金币 [ 分享文档获得金币 ] 2 人已下载

下载文档