2017-10-05 7 views
1

要するに、ネイティブメソッドは、loadLibrary呼び出しが発行されたのと同じクラスで宣言されている必要があります。ネイティブメソッドが静的内部クラスで宣言されている場合、バインディングは失敗します。java loadlibraryとネイティブメソッド宣言

実施例:

public class TestNative 
{ 
    public TestNative() 
    { 
     System.loadLibrary("mylibrary"); 
    } 

    private native int nativeMethod(); 

    public void doit() 
    { 
     new NativeWrap().callNative(); 
    } 

    class NativeWrap 
    { 
     int callNative() 
     { 
      return nativeMethod(); // <<<< works 
     } 
    } 
} 

失敗例:

public class TestNative2 
{ 
    public TestNative2() 
    { 
     System.loadLibrary("mylibrary"); 
    } 

    public void doit() 
    { 
     new NativeWrap().callNative(); 
    } 

    static class NativeWrap 
    { 
     int callNative() 
     { 
      return nativeMethod(); // <<<< throws UnsatisfiedLinkError 
     } 

     private native int nativeMethod(); 
    } 
} 

BTW:LoadLibraryの両方の例で動作します。

このトピックについてのヒントは見つかりませんでした。私が見つけたすべてのJNIの例は、ネイティブメソッドが宣言されているのと同じクラスにライブラリをロードします。誰かがこの物に光を当てることができますか?

+0

はどうなりますか? –

答えて

1

これは完全に正常に動作します。ライブラリをロードする場所は問題ではありません。ここで重要なのはメソッドの名前です。メソッドのシグネチャを生成し、メソッドを別の場所に移動すると、そのメソッドは実行されません。

はこちらをご覧ください:

package recipeNo001; 

public class HelloWorld { 

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

    private native void displayMessage(); 

    static class NativeWrapper { 
    void callNative() { 
     displayMessageInner(); 
    } 
    private native void displayMessageInner(); 
    } 

    public static void main(String[] args) { 
    new HelloWorld().displayMessage(); 
    new NativeWrapper().callNative(); 
    } 
} 

しかし、あなたは、ライブラリ内の適切な名前を提供することを確認する必要があります。 2つの違いに注意してください:

JNIEXPORT void JNICALL Java_recipeNo001_HelloWorld_displayMessage 
    (JNIEnv *env, jclass obj) 
JNIEXPORT void JNICALL Java_recipeNo001_HelloWorld_00024NativeWrapper_displayMessageInner 
    (JNIEnv *env, jobject obj) 

もちろん、それは動作します。

Hello world from enclosing class! 
Hello world from wrapper! 

あなたの場合、さらに別の問題があります。ライブラリをスタティックブロックにロードしない場合は、ネイティブメソッドを呼び出す前にクラスの少なくとも1つのオブジェクトをインスタンス化する必要があります。コードをサンプリングする来るとき

はこちらをご覧ください:あなたは、コンストラクタであなたのTestNative2クラスにライブラリをロードするのではなく、静的なブロックでそれをロードしない場合

https://github.com/mkowsiak/jnicookbook/tree/master/recipeNo034

+0

.oOo。ありがとう! JNIとお楽しみください! .oOo。 – mko