我有以下類別:的Java/JNI - UnsatisfiedLinkError在JNI_OnLoad
NativeClass.java
public class NativeClass {
public static final int CONSTANT_VALUE = getValue();
public static native int getValue();
}
TestClass.java
public class TestClass {
public static void main(String[] args) {
System.loadLibrary("native");
System.out.println(NativeClass.CONSTANT_VALUE);
}
}
C代碼:
#include <jni.h>
jint JNI_OnLoad(JavaVM *vm, void *reserved) {
JNIEnv *env = NULL;
if ((*vm)->GetEnv(vm, (void **) &env, JNI_VERSION_1_6) != JNI_OK) {
return JNI_ERR;
}
(*env)->FindClass(env, "LNativeClass;");
return JNI_VERSION_1_6;
}
JNIEXPORT jint JNICALL Java_NativeClass_getValue(JNIEnv *env, jclass cls) {
return 5;
}
我編譯了C文件是這樣的:
gcc NativeClass.c -I"JNI_HEADER_PATH" -shared -fPIC -o libnative.so
並執行這樣的代碼:
java -Djava.library.path=. TestClass
然後我得到以下異常:
Exception in thread "main" java.lang.UnsatisfiedLinkError: NativeClass.getValue()I
如果我移動System.loadLibrary("native");
靜態初始化程序塊NativeClass
它工作得很好:
public class NativeClass {
static {
System.loadLibrary("native");
}
public static final int CONSTANT_VALUE = getValue();
public static native int getValue();
}
我在這裏錯過了什麼? 這裏的代碼只是我在項目中遇到的確切錯誤的一個例子。 我絕對需要在NativeClass
中聲明常量,並且我還需要在JNI_OnLoad中找到類,因爲我必須在其中調用靜態方法。
那麼,什麼是錯的在靜態構造函數中保存'loadLibrary()'? –
我需要在'TestClass'中加載庫,而不是'NativeClass'。這只是一個例子。實際上,有許多具有本地功能的類。 'NativeClass'是唯一需要在'JNI_OnLoad'中訪問的類。以前,所有的文件都被編譯到一個單獨的庫中,該庫被加載到另一個類中,但是現在我將'NativeClass'的功能分離爲一個單獨的庫,該庫被加載到'NativeClass'的靜態初始化程序中。儘管如此,我想將所有內容都編譯到一個庫中。 – SomeRandomDude
好的,所以你的問題是你不能從不同的靜態構造函數中加載相同的庫。但爲什麼?看到這個[答案](http://stackoverflow.com/a/1133100/192373) –