![](/img/trans.png)
[英]Exception in thread "main" java.lang.UnsatisfiedLinkError"
[英]Java: Invoking native method giving “Exception in thread ”main“ java.lang.UnsatisfiedLinkError”
我正在嘗試從C ++調用Java中的簡單本機方法,以實現此目的,請執行以下操作:
創建一個簡單的類,如下所示:
public class HelloNative{ public native void printString(String str); static{ System.out.println("Current Directory is: " + System.getProperty("user.dir")); System.load(System.getProperty("user.dir") + "/libhellonative.so"); } public static void main(String[] args){ System.out.println("Calling Native Libraray (libhellonative.so) method printString"); new HelloNative().printString("Message from Java to C"); } }
使用javah -jni
為本機方法創建.h文件,該文件將創建以下聲明:
JNIEXPORT void JNICALL Java_HelloNative_printString(JNIEnv *, jobject, jstring);
將.cpp
文件中的本機功能實現為:
JNIEXPORT void JNICALL Java_HelloNative_printString(JNIEnv* jni_env, jobject java_obj, jstring msg){ printf("inside native method\\n"); jboolean iscopy; const char *message = (jni_env)->GetStringUTFChars( msg, &iscopy); printf("%s", message); }
最后使用以下命令創建.so
文件:
g++ HelloNative.cpp -o libhellonative.so -shared -Wl,-soname,libhellonative.so -static -lc -I /usr/lib/jvm/java-6-sun-1.6.0.26/include -I /usr/lib/jvm/java-6-sun-1.6.0.26/include/linux
但是當我編譯並運行.java文件時,它給了我Runtime Exception:
Current Directory is: /home/gmuhammad/Projects/test
Calling Native Libraray (libhellonative.so) method printString
Exception in thread "main" java.lang.UnsatisfiedLinkError: HelloNative.printString(Ljava/lang/String;)V
at HelloNative.printString(Native Method)
at HelloNative.main(HelloNative.java:16)
好的,我已經開始工作了。 它與加載庫無關,但實際上與從該庫中調用方法有關。
我通過從您的問題中復制/粘貼來創建.java
, .h
和.cpp
文件並運行它們(我必須在.cpp
文件中添加#include <jni.h>
)-並得到與您完全相同的錯誤。
然后,我編輯了.cpp
文件以包含生成的.h
文件。 另外,正如maba在他的回答中指出的那樣,您需要調用(jni_env)->ReleaseStringUTFChars(msg, message);
釋放對象。 我的完整.cpp
文件現在看起來像這樣:
#include "HelloNative.h"
JNIEXPORT void JNICALL Java_HelloNative_printString(JNIEnv* jni_env, jobject java_obj, jstring msg){
printf("inside native method\n");
jboolean iscopy;
const char *message = (jni_env)->GetStringUTFChars( msg, &iscopy);
printf("%s", message);
(jni_env)->ReleaseStringUTFChars(msg, message);
}
我重新編譯了庫,運行了Java代碼-瞧! 一切正常。 這樣,無論使用load
或loadLibrary
加載庫的方式如何,它都可以工作。
試試看。
我建議加載庫略有不同。
將您的libmynative.so
放在您喜歡的任何目錄中。
將該目錄添加到LD_LIBRARY_PATH
變量。
在您的Java代碼中,將System.load
調用更改為System.loadLibrary("mynative")
(請注意,缺少完整路徑,前綴lib和擴展名.so )
運行您的Java代碼。
在這里查看更多詳細信息: http : //java.sun.com/developer/onlineTraining/Programming/JDCBook/jniexamp.html
完全可以使用System.load()
但您必須確保共享庫確實位於您應說的位置。
Current Directory is: /home/gmuhammad/Projects/test
您的代碼正在嘗試訪問該目錄中的共享庫。 您確定libhellonative.so
在嗎?
然后,您還可以使用System.mapLibraryName("hellonative")
獲取當前平台的共享庫的名稱。 這使其與平台無關。 該調用將為您提供Linux上的libhellonative.so
和hellonative.dll
上的hellonative.dll
。
您還必須調用(jni_env)->GetReleaseUTFChars(msg, message);
釋放對象。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.