簡體   English   中英

Java:調用提供“線程“ main”中的異常” java.lang.UnsatisfiedLinkError的本機方法

[英]Java: Invoking native method giving “Exception in thread ”main“ java.lang.UnsatisfiedLinkError”

我正在嘗試從C ++調用Java中的簡單本機方法,以實現此目的,請執行以下操作:

  1. 創建一個簡單的類,如下所示:

     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"); } } 
  2. 使用javah -jni為本機方法創建.h文件,該文件將創建以下聲明:

    JNIEXPORT void JNICALL Java_HelloNative_printString(JNIEnv *, jobject, jstring);

  3. .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); } 
  4. 最后使用以下命令創建.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代碼-瞧! 一切正常。 這樣,無論使用loadloadLibrary加載庫的方式如何,它都可以工作。

試試看。

我建議加載庫略有不同。

  1. 將您的libmynative.so放在您喜歡的任何目錄中。

  2. 將該目錄添加到LD_LIBRARY_PATH變量。

  3. 在您的Java代碼中,將System.load調用更改為System.loadLibrary("mynative") (請注意,缺少完整路徑,前綴lib和擴展名.so

  4. 運行您的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.sohellonative.dll上的hellonative.dll

您還必須調用(jni_env)->GetReleaseUTFChars(msg, message); 釋放對象。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM