最近要使用JNI来做一些程序,花了一下午的时间,终于搞定,记录一下步骤,方便以后使用。
安装gcc等编译工具,我用的cygwin。。。真的很麻烦,不过终于搞定了。这个网上资料很多。
写natvie类,这个也没什么。
生成头文件,javah,也很简单,注意要用全路径,也就是包路径+类名,如java.lang.String
导入头文件和java的include里的所有文件也没问题。
编写c文件。
正戏来了,在编译成dll文件的时候,出现了十分令人郁闷的问题,java.lang.UnsatisfiedLinkError;hellonative.Main.nativePrint()V。这个说明dll文件找到了,但是方法找不到,经过查找,原来是编译的时候参数没有设置清楚,正确的应该是
-mno-cygwin -Wl,--kill-at -shared -m32
其中-mno-cygwin是说脱离cygwin环境,-m32是编译成32位,这两个一般情况下是可选的。--kill-at是关键,这个是说生成的文件中不要有@,必须要有该参数,否这就抛上面的异常。
另如果想把dll文件打包进jar中,可以用到下面的代码来做:
static {
try {
InputStream inputStream = Main.class.getResourceAsStream("HelloNative.dll");
// System.out.println(inputStream);
File temporaryDll = File.createTempFile("HelloNative", ".dll");
// System.out.println(temporaryDll.getAbsolutePath());
FileOutputStream outputStream = new FileOutputStream(temporaryDll);
byte[] array = new byte[8192];
int i = -1;
while ((i = inputStream.read(array)) != -1) {
outputStream.write(array, 0, i);
}
outputStream.close();
temporaryDll.deleteOnExit();
System.out.println(temporaryDll.getAbsolutePath());
System.load(temporaryDll.getPath());
} catch (Exception e) {
e.printStackTrace();
}
}
把文件复制进临时文件夹调用,因为system.load不能访问jar文件。