Android NDK C ++ JNI (aucune implémentation native trouvée pour ...)
-
25-09-2019 - |
Question
Je suis en train d'utiliser le NDK avec C ++ et ne peut pas sembler obtenir la convention de nommage de méthode. 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ée dans extern "C" {} ASLO.
Tout compile bien, crée un fichier .so et copie dans le dossier libs dans mon projet, mais quand je debug et exécuter dans Eclipse je continue à avoir un message de chat de journal de « aucune implémentation trouvée pour natif ... ». Y at-il quelque chose que je suis absent que tous les exemples NDK sont en C?
Merci.
La solution
Il y a deux choses qui peuvent conduire à « aucune mise en œuvre trouvée ». L'un est d'obtenir le nom du prototype de mauvaise fonction, une autre est le échec du chargement .donc du tout. Etes-vous sûr System.loadLibrary()
est appelée avant la méthode est utilisée?
Si vous ne disposez pas d'une fonction de JNI_OnLoad
définie, vous pouvez créer un et avoir craché un message de journal juste pour vérifier que la lib est de se tiré dans avec succès.
Vous avez déjà esquivé le problème le plus commun - oublier d'utiliser extern "C"
- il est donc soit au-dessus ou d'une légère faute d'orthographe. Qu'est-ce que la déclaration de Java ressembler?
Autres conseils
Une autre cause de cette erreur: le nom de la méthode native undecorated ne doit pas contenir un trait de soulignement
Par exemple, je voulais exporter une fonction C nommée AudioCapture_Ping()
. Voici ma déclaration d'exportation dans C:
JNI_EXPORT int Java_com_obsidian_mobilehashhost_MainActivity_AudioCapture_Ping(JNIEnv *pJniEnv, jobject object); //Notice the underscore before Ping
Voici été ma classe Java importe la fonction:
package com.obsidian.mobileaudiohashhost;
...
public class MainActivity extends Activity {
private native int AudioCapture_Ping(); // FAILS
...
Je ne pouvais pas Android pour lier dynamiquement à ma méthode native jusqu'à ce que j'enlevé 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!
...
J'ai eu le même problème, mais pour moi l'erreur était dans le fichier Android.mk. Je l'ai eu:
LOCAL_SRC_FILES := A.cpp
LOCAL_SRC_FILES := B.cpp
mais devrait avoir ceci:
LOCAL_SRC_FILES := A.cpp
LOCAL_SRC_FILES += B.cpp
noter les détails + = au lieu : =
J'espère que cela aide.
appelé extern « C » comme il est prévu dans l'exemple studio généré automatiquement, mais il a oublié d'envelopper tout le reste du dossier, y compris les fonctions suivantes, entre parenthèses {}. Seule la première fonction a travaillé.
Une raison supplémentaire: utilisation LOCAL_WHOLE_STATIC_LIBRARIES au lieu de LOCAL_STATIC_LIBRARIES dans android.mk. Cela empêche la bibliothèque de l'optimisation des appels API inutilisés parce que le NDK ne peut pas détecter l'utilisation des liaisons natives à partir du code java.
Il est un exemple de cpp sous des applications dans NDK:
Utilisation javah (partie de Java SDK). Son l'outil exactement pour cela (génère en-tête .h du fichier .class).
Si votre nom de package comprend _ caractère, vous devez écrire une (1) après le caractère _ comme indiqué ci-dessous:
MainActivity.java
package com.example.testcpp_2;
-lib.cpp natif
JNICALL
Java_com_example_testcpp_12_MainActivity_stringFromJNI(
J'essaie toutes les solutions ci-dessus, mais personne ne peut résoudre mon erreur de construction (JNI java.lang.UnsatisfiedLinkError: Pas de mise en œuvre trouvée pour ...), enfin je trouve que j'oublie d'ajouter mon fichier source verify.cpp à CMakeList.txt add_library segement (verify.cpp est auto générer par Ctrl + Entrée clé courte, peut-être un autre nom de fichier), espère que ma réponse peut aider quelqu'un.
mon environnement de construction: Gradle + CMake
Face au même problème, et dans mon cas, la raison était que je devais souligner le nom de package « RFID_Test » Je le package et retitré cela a fonctionné. user1222021 Merci
Je fait face à deux fois le même problème. Il est arrivé, que le téléphone j'ai essayé de démarrer l'application à partir d'Android studio a utilisé un niveau de l'API que je ne l'ai pas encore téléchargé dans Android Studio.
- Mise à jour Android Studio la dernière version
- Télécharger l'API nécessaire à partir de Android Studio est