2015-10-30 151 views
1
找到上課的時候

我有以下類別:的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中找到類,因爲我必須在其中調用靜態方法。

+0

那麼,什麼是錯的在靜態構造函數中保存'loadLibrary()'? –

+0

我需要在'TestClass'中加載庫,而不是'NativeClass'。這只是一個例子。實際上,有許多具有本地功能的類。 'NativeClass'是唯一需要在'JNI_OnLoad'中訪問的類。以前,所有的文件都被編譯到一個單獨的庫中,該庫被加載到另一個類中,但是現在我將'NativeClass'的功能分離爲一個單獨的庫,該庫被加載到'NativeClass'的靜態初始化程序中。儘管如此,我想將所有內容都編譯到一個庫中。 – SomeRandomDude

+0

好的,所以你的問題是你不能從不同的靜態構造函數中加載相同的庫。但爲什麼?看到這個[答案](http://stackoverflow.com/a/1133100/192373) –

回答

0

mainTestClass的一部分,在加載TestClass之前無法調用。但TestClass不能被加載,直到調用System.loadLibrary("native");

所以這

public static void main(String[] args) { 
    System.loadLibrary("native"); 

永遠不能稱之爲 - 調用main取決於所加載的類依賴於loadLibrary被稱爲取決於main被稱爲....

+0

'TestClass'雖然加載,但如果我在加載庫TestClass之前打印出來,它會被打印。 – SomeRandomDude