调试一个HelloWorld的jni调用,费了半天劲。各种坑
用eclipse建立的java部分工程,用visual studio 2017建立的dll工程。
注意用dll工程,不要用其他的windows控制台应用程序。
坑1:
no HelloNative in java.library.path
需要设置临时的环境变量,系统变量和java library库找不到我们生产的dll库。
VM arguments中设置-Djava.library.path=”${workspace_loc:TestZhuanYongProject}\bin”
TestZhuanYongProject为工程名,我把dll库copy到TestZhuanYongProject的bin目录下了。
坑2:
“stdafx.h”的问题 ——- 有时候生产解决方案的时候报这个错误,可以设置不使用预编译头来解决。
坑3:
#include <jni.h> java自动生成的.h头文件是用尖括号的,需要改成“jni.h”。尖括号表示系统库,本来jni.h和jni_md.h没有
在VS的默认系统库的头文件中的。
坑4:
有几次使用vs自带的命令行使用cl/DL 命令生成dll文件
dll: Can’t load IA 32-bit .dll on a AMD 64-bit platform
原因是使用的32位命令,生成了32位的dll库,但是调用的java环境却是64位。
LINK : fatal error LINK156: 必须定义入口点
原因是一开始创建的并不是dll工程,而是控制台工程,要求必须有main函数作为入口点。
坑5:
头文件com_test_jni_HelloNative.h文件
1 | /* DO NOT EDIT THIS FILE - it is machine generated */ |
源文件com_test_jni_HelloNative.cpp文件
1 |
|
标红部分jclass obj和jclass一定要注意,如果java文件定义的原生方法是static,那么生成的native的h文件就是jclass;
如果不是static,生成的native的h文件就是jobject。然后cpp文件实现的时候一定要注意跟h文件的方法定义一致,否则你怎么也不会调通的。大坑
会一直报错:java.lang.UnsatisfiedLinkError: com.test.jni.HelloNative.sayHello()V找不到对应的方法。
另外,linux下编程,注意这个问题:
着急的去网上搜索问题,没有注意的在linux下,动态链接库的名字 必须是 lib****.so,必须以lib开头!