2015-09-29 60 views
1

我正在編寫一個簡單的Hello World Java程序來調用本地庫中的代碼。然而,當我運行程序時,我收到以下錯誤:
加載JNI庫時出現不滿意的鏈接錯誤

Exception in thread "main" java.lang.UnsatisfiedLinkError: no TestJNI in java.library.path 
    at java.lang.ClassLoader.loadLibrary(ClassLoader.java:1764) 
    at java.lang.Runtime.loadLibrary0(Runtime.java:823) 
    at java.lang.System.loadLibrary(System.java:1044) 
    at TestJNI.<clinit>(TestJNI.java:4) 

下面是代碼:
的Java:

//filename: TestJNI.java 

public class TestJNI{ 

    static{ 
     System.loadLibrary("TestJNI"); 
    } 

    private native void helloWorld(); 

    public static void main(String[] args){ 
     new TestJNI().helloWorld(); 
    } 
} 

C:

//filname:TestJNI.c 

#include <jni.h> 
#include <stdio.h> 
#include "TestJNI.h" 

JNIEXPORT void JNICALL Java_TestJNI_helloWorld(JNIEnv *env, jobject thisObj){ 
    printf("Hello World!\n"); 
    return; 
} 

的C文件使用以下編譯器,標誌和參數進行編譯:
clang -o TestJNI.jnilib -I/System/Library/Frameworks/JavaVM.framework/Headers -lc -shared TestJNI.c
那麼Java應用程序如下運行:
java -Djava.library.path=. TestJNI

我編譯和運行Mac OS X上的優勝美地的文件。有誰知道我做錯了什麼?

回答

1

驗證java.library.path變量指向包含TestJNI庫的目錄。 您可以嘗試

System.setProperty("java.library.path", "...directory path...");

另外,使用System.load("...full path to TestJNI...");這需要到庫(包括文件擴展名)的完整路徑。 (System.loadLibrary推斷我相信的文件擴展名)

+0

我正在將C文件編譯到Java應用程序所在的相同目錄。是否還需要包含完整路徑名? –

+0

如果使用'System.load'加載庫,則只需要包含完整路徑。如果使用'System.loadLibrary',則只包含庫文件的名稱(不包含擴展名)。在後一種情況下,您還必須確保java.library.path指向該目錄。我建議前一種情況,它更明確。 –

+0

您的解決方案有效!不過,我仍然想知道如何在不指定完整路徑名的情況下加載庫。當我運行應用程序時,將'-Djava.library.path = .'作爲參數傳遞是否有問題?或者,你有其他建議嗎? –

0

您的庫應該命名爲.so以便它可以作爲共享庫加載。我相信你的編譯行應該是這個樣子:

鐺-shared -undefined dynamic_lookup -o TestJNI.so -I /系統/資源庫/框架/ JavaVM.framework /頭-lc TestJNI.c

+0

我在OS X上,因此庫文件擴展名與.jnilib文件一樣正確。你有什麼其他的建議? –

相關問題