J'essaie d'utiliser le NDK avec C ++ et je n'arrive pas à obtenir la convention de dénomination de méthode correcte. ma méthode native est la suivante:
extern "C" {
JNIEXPORT void JNICALL Java_com_test_jnitest_SurfaceRenderer_drawFromJni
(JNIEnv* env, jclass c)
{
//
}
}
avec un en-tête enveloppé dans extern "C" {} également.
Tout se compile correctement, crée un fichier .so et se copie dans le dossier libs sous mon projet, mais quand je débogue et que je lance dans Eclipse, je continue à recevoir un message de chat de journal indiquant "aucune implémentation trouvée pour le natif ...". Y a-t-il quelque chose qui me manque car tous les exemples NDK sont en C?
Merci.
android
android-ndk
Patrick Kafka
la source
la source
javah
? Sinon, vous devriez l'être. :-PSystem.loadLibrary
Réponses:
Il y a plusieurs choses qui peuvent conduire à "aucune implémentation trouvée". L'un se trompe sur le nom du prototype de la fonction, un autre ne parvient pas du tout à charger le .so. Êtes-vous sûr que cela
System.loadLibrary()
est appelé avant que la méthode ne soit utilisée?Si vous n'avez pas
JNI_OnLoad
défini de fonction, vous voudrez peut-être en créer une et lui faire cracher un message de journal juste pour vérifier que la bibliothèque est bien insérée.Vous avez déjà esquivé le problème le plus courant - oublier d'utiliser
extern "C"
- c'est donc soit le problème ci-dessus, soit une légère faute d'orthographe. À quoi ressemble la déclaration Java?la source
Une cause supplémentaire de cette erreur: votre nom de méthode native non décoré ne doit pas contenir de trait de soulignement!
Par exemple, je voulais exporter une fonction C nommée
AudioCapture_Ping()
. Voici ma déclaration d'exportation en C:JNI_EXPORT int Java_com_obsidian_mobilehashhost_MainActivity_AudioCapture_Ping(JNIEnv *pJniEnv, jobject object); //Notice the underscore before Ping
Voici ma classe Java important la fonction:
package com.obsidian.mobileaudiohashhost; ... public class MainActivity extends Activity { private native int AudioCapture_Ping(); // FAILS ...
Je ne pouvais pas faire en sorte qu'Android se lie dynamiquement à ma méthode native jusqu'à ce que j'aie supprimé le trait de soulignement:
JNI_EXPORT int Java_com_obsidian_mobilehashhost_MainActivity_AudioCapturePing(JNIEnv *pJniEnv, jobject object); package com.obsidian.mobileaudiohashhost; ... public class MainActivity extends Activity { private native int AudioCapturePing(); // THIS WORKS! ...
la source
J'ai eu le même problème, mais pour moi, l'erreur était dans le fichier Android.mk. Je l'avais:
mais devrait avoir ceci:
notez le détail + = à la place : =
J'espère que cela aide.
la source
Appelé extern "C" comme indiqué dans l'exemple Studio généré automatiquement, mais j'ai oublié de placer le reste du fichier, y compris les fonctions suivantes, entre crochets {}. Seule la première fonction a fonctionné.
la source
Une raison supplémentaire: utilisez LOCAL_WHOLE_STATIC_LIBRARIES au lieu de LOCAL_STATIC_LIBRARIES dans android.mk. Cela empêche la bibliothèque d'optimiser les appels d'API inutilisés car le NDK ne peut pas détecter l'utilisation des liaisons natives du code java.
la source
Il y a un exemple de cpp sous les applications dans ndk: https://github.com/android/ndk-samples/blob/master/hello-gl2/app/src/main/cpp/gl_code.cpp
la source
Utilisez javah (qui fait partie du SDK Java). C'est l'outil exactement pour cela (génère un en-tête .h à partir du fichier .class).
la source
Si le nom de votre package comprend le caractère _, vous devez écrire 1 (un) après le caractère _ comme indiqué ci-dessous:
MainActivity.java
package com.example.testcpp_2;
native-lib.cpp
la source
J'essaie toutes les solutions ci-dessus, mais personne ne peut résoudre mon erreur de construction (jni java.lang.UnsatisfiedLinkError: Aucune implémentation trouvée pour ...), enfin j'ai trouvé que j'avais oublié d'ajouter mon fichier source verify.cpp à CMakeList.txt add_library segement (verify.cpp est généré automatiquement par Ctrl + Entrée, peut-être un autre nom de fichier), j'espère que ma réponse pourra aider quelqu'un.
mon environnement de construction: Gradle + CMake
la source
J'ai fait face au même problème, et dans mon cas, la raison était que j'avais un trait de soulignement dans le nom du paquet "RFID_Test" J'ai renommé le paquet et cela a fonctionné. Merci user1222021
la source
J'ai rencontré deux fois le même problème. Il est arrivé que le téléphone sur lequel j'ai essayé de démarrer l'application à partir d'Android Studio utilisait un niveau d'API que je n'ai pas encore téléchargé dans Android Studio.
la source