使用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爲參數