2010-10-27 17 views
19

J'ai une implémentation fonctionnelle de la bibliothèque NDK et de la classe Java correspondante. Mais je ne suis pas capable d'ajouter une méthode surchargée à cette classe. À l'heure actuelle ma classe contient:Quelle est la manière correcte d'écrire des signatures de méthode native dans Android NDK?

package com.package; 

public class MyClass 
{ 
    public static native String getFileName(); 
    static 
    { 
    System.loadLibrary("mylib"); 
    } 
} 

Mon fichier jniwrappers.cpp a la déclaration suivante:

JNIEXPORT jstring JNICALL 
Java_com_package_MyClass_getFileName(_JNIEnv* env, jobject thiz); 

Jusqu'à ce point, tout fonctionne bien. Mais à côté je modifie ma classe:

package com.package; 

public class MyClass 
{ 
    public static native String getFileName(); 
    public static native String getFileName(int index); 
    ... 
} 

Et ajouter à jniwrappers.cpp une autre déclaration:

JNIEXPORT jstring JNICALL 
Java_com_package_MyClass_getFileName__I(_JNIEnv* env, jobject thiz, jint index); 

Il compile bien, l'application Android commence, ne reçoit pas UnsatisfiedLinkError mais quand il appelle la deuxième méthode avec l'argument la première fonction C++ est appelée mais pas la seconde. J'ai d'autres méthodes avec des arguments dans cette classe mais aucune d'entre elles n'est surchargée de sorte que leurs signatures JNI respectives ne contiennent pas d'arguments.

Alors, qu'est-ce que je fais de mal?

Répondre

20

Vous devez ajouter un __ à la fin de la fonction getFileName d'origine maintenant qu'il est surchargé. Vos 2 prototypes de fonction C devraient ressembler à ceci:

JNIEXPORT jstring JNICALL Java_com_package_MyClass_getFileName__ 
    (JNIEnv *, jclass); 

JNIEXPORT jstring JNICALL Java_com_package_MyClass_getFileName__I 
    (JNIEnv *, jclass, jint); 
+0

C'était la première chose que j'ai essayée mais quelque chose s'est mal passé et j'ai UnsatisfiedLinkError. Maintenant j'ai réessayé ceci et ai tout fonctionné. Merci beaucoup! –

25

Vous devez utiliser l'outil javah pour générer ces signatures. Pour l'utiliser, créez le fichier de classe dans lequel vous avez votre fonction native. Vous obtiendrez un fichier class.

Exécutez javah -jni com.organisation.class_with_native_func, cela générera un fichier d'en-tête pour vous.

C'est beaucoup plus propre que de l'éditer vous-même.

+3

Merci, c'est ce que je devrais utiliser. Mais savoir encore les internes est très utile. –

+0

Ou utilisez simplement l'option de ligne de commande -classpath pour diriger javah vers le répertoire où votre fichier de classe est compilé (par exemple: 'javah -classpath/chemin/vers/jar -jni com.package.name.YourClass'). –