Java JNI调用c语言的dll测试
最近复习C语言和java语言(10年没用了,温习一下),用JNI调用C语言的dll测试,以前没做过,在网上找了很多,总结如下:
环境:windows 10(64位) + JDK(32位,版本1.7.0_79) + MinGW(32位),注意JDK和MinGW要么都是32位,要么都是64位,不能一个是32位另一个是64位。
java和MinGW的环境配置在网上查找。
一、【不用eclipse,用记事本手工编辑 .java和 .c 程序】
1、hello.java代码如下:
2、编译Hello.java程序命令:javac Hello.java --生成Hello.class文件。
3、生成Hello.h文件命令:javah Hello --生成Hello.h头文件,该头文件在C语言编码中要用到,所以将Hello.h存放到后缀为 .c 文件代码相同的目录。
4、arr.c文件内容如下:
5、C编译环境准备:需要将JDK对应的 jni_md.h 和 jni.h 两个文件拷贝到MinGW的安装目录的include目录下。
jni_md.h在 %JAVA_HOME%\ include\win32目录下; jni.h在%JAVA_HOME%\ include目录下。
如果不想拷贝,则在下面的6步命令末尾需要添加如下内容:
-I"C:\Program Files (x86)\Java\jdk1.7.0_79\include" -I"C:\Program Files (x86)\Java\jdk1.7.0_79\include\win32"
其中,JAVA_HOME=C:\Program Files (x86)\Java\jdk1.7.0_79. 根据自己的JAVA_HOME路径修改。
添加双引号是因为gcc命令行解释不了”Program Files (x86)“中的空格字符。
6、编译生成 hello.dll 动态库文件命令:
gcc arr.c -shared -o hello.dll -Wl,--kill-at
命令解释:
-shared -o hello.dll /* 指定编译生成的目标文件 hello.dll是动态库文件 */
-Wl /* 告诉编译器将后面的参数传递给链接器 */
-Wl,--kill-at /*告诉链接器去掉函数名称后缀的@符号 --该问题涉及比较深入的东西,暂时不管,只管按命令执行,生成 .dll 文件,实现测试目的。*/
7、检查测试目录 E:\test下的文件如下 :
8、执行 java Hello,成功!
二、【使用Eclipse编辑】
使用 eclipse 编辑的区别主要在 JAVA 源程序常常装在 package 中,所以需要特别处理一下:
1、编辑完成 .java 代码后,就用eclipse 编译成.class文件。
2、使用javah -o E:\test\com_test_HelloWorld.h -classpath $ProjectPath\build\classes com.test.HelloWorld
$ProjectPath :该路径指eclipse中生成HelloWorld.java项目的路径。
注意:com.test.HelloWorld这个名称一定要按自己的 package 顺序写完。
3、使用命令行生成JNI格式的C语言头文件.h文件:
gcc arr.c -shared -o 希望存放的路径\hello.dll -Wl,--kill-at -I"JDK安装路径\include" -I"JDK安装路径\include\win32"
希望存放的路径:指生成的hello.dll文件存放路径。
JDK安装路径: 指自己的JAVA_HOME目录路径。
4、在 eclipse的项目配置中(右键项目名称->Build Path -> Configure Build Path,然后选择 Java Build Path ,在右边的Source 页展开当前项目;
然后,选中Native Library Location,点击“Edit” ,再选择“Workspace”,将第3步生成的 .dll 文件目录添加到项目中。
5、运行HelloWorld,成功!
三、JNI测试常见错误 java.lang.UnsatisfiedLinkError:
参考:http://blog.csdn.net/binyao02123202/article/details/18075747
http://blog.csdn.net/niuxinlong/article/details/4176612