1

私は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ファイルをコンパイルして実行すると、ランタイム例外が発生します。

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)
4

3 に答える 3

3

わかりました、これを機能させました。ライブラリのロードとは関係ありませんが、実際にそのライブラリからメソッドを呼び出すこととは関係ありません。

私はあなたの質問からコピー/貼り付けによってファイルを作成し、それらを実行しました(私はファイルに追加する必要があり.javaました)-そしてあなたがしたのとまったく同じエラーが発生しました。.h.cpp#include <jni.h>.cpp

.cpp次に、生成されたファイルを含めるようにファイルを編集しました.h。また、マバ(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

試してみる。

于 2012-08-21T16:14:42.630 に答える
1

ライブラリのロード方法を少し変えることをお勧めします。

  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

于 2012-08-21T13:48:22.007 に答える
1

使用してもまったく問題System.load()ありませんが、共有ライブラリが実際に本来あるべき場所にあることを確認する必要があります。

Current Directory is: /home/gmuhammad/Projects/test

コードは、そのディレクトリ内の共有ライブラリにアクセスしようとしています。そこにあると確信していますlibhellonative.soか?

次に、を使用しSystem.mapLibraryName("hellonative")て、現在のプラットフォームの共有ライブラリの名前を取得することもできます。これにより、プラットフォームに依存しなくなります。この呼び出しlibhellonative.soにより、Linuxとhellonative.dllWindowsが表示されます。

(jni_env)->GetReleaseUTFChars(msg, message);また、オブジェクトを解放するために呼び出す必要があります。

于 2012-08-21T14:38:32.587 に答える