使用JNI的原因,java项目中有时会调用本地方法,如c/c++的方法,采用JNI可以实现,相关实现方式还有JNA,JNative。
JNI的使用方式
- 在java中声明native方法
package com.test.nativeDemo;
public class NativeTest {
public static native int add(int a, int b);
}
- 生成.h(c/c++头文)文
- javac NativeTest 生成 NativeTest .clas文件
- 在com的父目录下 运行 javah -jni com.test.nativeDemo.NativeTest 注意一定要在包的父级目录下运行,不然找不到NativeTest这个class
- 运行完上面命令就会在com的父级目录出现.h
com_test_nativeDemo_NativeTesh.h
用这个.h文件去visual studio生成dll文件。采用c/c++实现的时候,这个.h文件当作头文件,这个时候需要再dll项目中引入jdk相关dll。
- 生成dll后,我们在java文件中就可以引入了,将生成的dll文件放到jdk中,具体方法如图:
- 生成dll后,我们在java文件中就可以引入了,将生成的dll文件放到jdk中,具体方法如图:
在java代码中引入dll文件
package com.test.nativeDemo;
public class NativeTest {
static {
System.loadLibrary("NativeTest");
}
public static native int add(int a, int b);
public static void main(String[] args) {
System.out.println(add(1, 2));
}
}
注意
- 以下代码为生成的.h文件内容:
/* DO NOT EDIT THIS FILE - it is machine generated */
#include <jni.h>
/* Header for class com_test_nativeDemo_NativeTest */
#ifndef _Included_com_test_nativeDemo_NativeTest
#define _Included_com_test_nativeDemo_NativeTest
#ifdef __cplusplus
extern "C" {
#endif
/*
* Class: com_test_nativeDemo_NativeTest
* Method: add
* Signature: (II)I
*/
JNIEXPORT jint JNICALL Java_com_test_nativeDemo_NativeTest_add
(JNIEnv *, jclass, jint, jint);
#ifdef __cplusplus
}
#endif
#endif
其中 c/c++中如果JNIEnv 显示报错说明你没有引入jdk相关文件,include,/include/win32/bridge这些文件, t特别注意java到c/c++的变量类型的转化与回收。
报java.lang.UnsatisfiedLinkError: no NativeTest in java.library.path这个错,是没有将dll文件放到jdk中
如果生成的dll文件的位数与jdk的位数不同,同样会报java.lang.UnsatisfiedLinkError异常
如果报A fatal error has been detected by the Java Runtime Environment这个错有可能是传入了null值,jni禁止传入null为参数