2017-10-05 1 views
1

En résumé: Une méthode native doit évidemment être déclarée dans la même classe que l'appel loadLibrary. Si la méthode native est déclarée dans une classe interne statique, la liaison échoue.java loadlibrary et déclaration de méthode native

Exemple de travail:

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 
     } 
    } 
} 

exemple défaut:

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: Le loadLibrary fonctionne dans les deux exemples.

Je n'ai trouvé aucun indice à ce sujet. Tous les exemples JNI que j'ai trouvés charger la bibliothèque dans la même classe que la méthode native est déclarée. Quelqu'un peut-il faire la lumière sur ce genre de choses?

+0

Qu'advient-il si vous ne chargez pas la bibliothèque dans votre classe TestNative2 dans le constructeur, mais plutôt de le charger dans un bloc statique? –

Répondre

1

Cela fonctionne parfaitement bien. Lieu, où vous chargez la bibliothèque, n'a pas d'importance. Ce qui compte ici, c'est le nom de la méthode. Si vous générez votre signature de méthode, puis déplacez votre méthode ailleurs, elle échouera.

Jetez un oeil ici:

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(); 
    } 
} 

Mais vous devez vous assurer que vous fournissez nom propre à l'intérieur de la bibliothèque. Notez la différence entre deux:

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

Et cela fonctionne, bien sûr.

Hello world from enclosing class! 
Hello world from wrapper! 

Et, dans votre cas, vous avez encore un autre problème. Si vous ne chargez pas la bibliothèque dans un bloc statique, vous devez vous assurer d'instancier au moins un objet de la classe avant d'appeler la méthode native.

Jetez un coup d'oeil ici en ce qui concerne des échantillons de code:

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

+0

.oOo. Merci! Amusez-vous avec JNI! .oOo. – mko