Android - échec du chargement de la bibliothèque
J'ai un problème similaire à cette question, mais légèrement différente. J'ai compilé une .afin de bibliothèque à utiliser avec JNI. Parce qu'il est de grande taille (15 MO), je suis le mettre sur la carte sd au lieu de la norme du lieu d'application.
Le fichier est appelé libSample.donc, et il est situé à la /data/library/libSample.so
- Je le charger dans un bloc d'initialisation statique:
try {
File sdcard = Environment.getExternalStorageDirectory();
File libraryLoc = new File(sdcard.getAbsolutePath() + "/library/libSample.so");
Log.i("Library", "Does the library exist?" + libraryLoc.exists());
System.load(libraryLoc.getAbsolutePath());
}
catch (UnsatisfiedLinkError e) {
Log.e("Translator", e.getMessage());
Log.e("Translator", e.toString());
}
Voici pertinentes logcat de sortie:
09-02 16:42:58.882: DEBUG/dalvikvm(4185): Trying to load lib /data/data/com.example.hellojni/lib/libhello-jni.so 0x434fb6f8
09-02 16:42:58.892: DEBUG/dalvikvm(4185): Added shared lib /data/data/com.example.hellojni/lib/libhello-jni.so 0x434fb6f8
09-02 16:42:58.892: DEBUG/dalvikvm(4185): No JNI_OnLoad found in /data/data/com.example.hellojni/lib/libhello-jni.so 0x434fb6f8
09-02 16:42:58.892: INFO/Library(4185): Library exists: true
09-02 16:42:58.902: INFO/Library(4185): Library can be read: true
09-02 16:42:58.902: DEBUG/dalvikvm(4185): Trying to load lib /sdcard/library/libSample.so 0x434fb6f8
09-02 16:42:58.902: INFO/dalvikvm(4185): Unable to dlopen(/sdcard/library/libSample.so): Cannot find library
09-02 16:42:58.912: ERROR/Translator(4185): Library /sdcard/library/libSample.so not found
09-02 16:42:58.912: ERROR/Translator(4185): java.lang.UnsatisfiedLinkError: Library /sdcard/library/libSample.so not found
Aucune idée de quel est le problème?
J'ai lu le post sur pouvez android charger la dll à partir de carte sd en mode natif qui a dit que la carte sd ne peut pas être utilisé pour charger des bibliothèques, j'ai donc déplacé le .donc dans /data/data/com.exemple.hellojni/lib/libSample.(l'application privée emplacement de stockage de données). Pas de changement:
09-02 16:53:18.332: DEBUG/dalvikvm(4515): Trying to load lib /data/data/com.example.hellojni/lib/libhello-jni.so 0x434fb6f8
09-02 16:53:18.342: DEBUG/dalvikvm(4515): Added shared lib /data/data/com.example.hellojni/lib/libhello-jni.so 0x434fb6f8
09-02 16:53:18.342: DEBUG/dalvikvm(4515): No JNI_OnLoad found in /data/data/com.example.hellojni/lib/libhello-jni.so 0x434fb6f8
09-02 16:53:18.352: INFO/Library(4515): Library exists: true
09-02 16:53:18.352: INFO/Library(4515): Library can be read: true
09-02 16:53:18.352: DEBUG/dalvikvm(4515): Trying to load lib /data/data/com.example.hellojni/lib/libSample.so 0x434fb6f8
09-02 16:53:18.482: INFO/dalvikvm(4515): Unable to dlopen(/data/data/com.example.hellojni/lib/libSample.so): Cannot find library
09-02 16:53:18.492: ERROR/Translator(4515): Library /data/data/com.example.hellojni/lib/libSample.so not found
09-02 16:53:18.492: ERROR/Translator(4515): java.lang.UnsatisfiedLinkError: Library /data/data/com.example.hellojni/lib/libSample.so not found
Ce que je ne comprends pas, c'est que clairement la bibliothèque existe, et le système d'exploitation tente de charger ... donc qu'est ce qui ferait échouer?
Suivant les conseils de l'un des intervenants, j'ai essayé attachant via strace pour obtenir plus d'informations détaillées sur l'erreur. Le journal peut être trouvé comme un github gist.
L'erreur semble être sur les lignes 47-51:
mprotect(0x4235d000, 4096, PROT_READ) = 0
ioctl(1, SNDCTL_TMR_TIMEBASE or TCGETS, 0xbeb58080) = -1 ENOTTY (Not a typewriter)
write(1, "bionic/linker/linker.c:1243| ERROR: 34 unknown reloc type 3 @ 0x811a854c (2441)\n", 83) = 83
write(1, "bionic/linker/linker.c:1641| ERROR: failed to link /data/data/com.example.hellojni/lib/libSample.so\n", 100) = 100
munmap(0x81000000, 8839168) = 0
Voici la readelf de la bibliothèque:
arm-eabi-readelf -d libSample.so
Dynamic section at offset 0x80b648 contains 17 entries:
Tag Type Name/Value
0x00000019 (INIT_ARRAY) 0x7ff234
0x0000001b (INIT_ARRAYSZ) 76 (bytes)
0x00000004 (HASH) 0xd4
0x00000005 (STRTAB) 0x7f41c
0x00000006 (SYMTAB) 0x2650c
0x0000000a (STRSZ) 1197287 (bytes)
0x0000000b (SYMENT) 16 (bytes)
0x00000003 (PLTGOT) 0x80c6f0
0x00000002 (PLTRELSZ) 76480 (bytes)
0x00000014 (PLTREL) REL
0x00000017 (JMPREL) 0x1ccb84
0x00000011 (REL) 0x1a3904
0x00000012 (RELSZ) 168576 (bytes)
0x00000013 (RELENT) 8 (bytes)
0x00000016 (TEXTREL) 0x0
0x6ffffffa (RELCOUNT) 2412
0x00000000 (NULL) 0x0
Quelle est la version d'Android que vous utilisez? Les versions les plus récentes sont un peu plus prolixe au sujet de dlopen() échecs. Les anciennes versions de l'éditeur de liens dynamique déclarés "non trouvé" pour tout. Une chose qui aide parfois est de mettre en place une mince ligne de commande programme en C qui ne fait rien, mais l'appel dlopen() sur votre lib et de faire rapport sur le résultat. Si elle échoue, vous savez que c'est une lib problème; s'il réussit, le problème est ailleurs.
Comment compiler un programme avec l'android cross compilateur? Je ne sais pas où trouver les symboles non résolus dlopen, dlerror, etc. arm-eabi-nm -u libTester.exe U __aeabi_détendez-vous_rpc_pr1 U __gxx_la personnalité_v0 U __sF U dlclose U dlerror U dlopen U dlsym U fprintf
OriginalL'auteur I82Much | 2010-09-02
Vous devez vous connecter pour publier un commentaire.
Je pense qu'il peut être plus probable qu'une bibliothèque .donc dépend n'est pas trouvé. Mais c'est seulement si .les fichiers peuvent être chargés à partir d'une carte sd dans la première place.
Je vous entends, JNI est toujours tellement amusant
Merci - je ne faisais que regarder l'erreur et la ligne de code. S'avère que le véritable message d'erreur dans le débogueur a indiqué une dépendance qu'il ne pouvait pas trouver.
OriginalL'auteur Paul Gregoire
Ne
libSample.so
de dépendances sur d'autres shared libs que vous pouvez être en train de bâtir? Si oui, vous aurez besoin deSystem.loadLibrary
ouSystem.load
ses dépendances première, faire assurez-vous de charger la plupart de la "base" des bibliothèques, avant les autres, comme s'ils étaient des bibliothèques statiques. Au moins, il semble de cette façon avec le NDK 7b.Par exemple, si
libSample.so
dépendlibfoo.so
vous devriez faire quelque chose comme:J'ai ajouté un exemple pour le chargement des dépendances à cette réponse.
Fonctionne pour moi! Je me demande ce que Nexus accepté toute commande de bibliothèques, mais le Kindle Fire n'est pas!
peut-être il y a eu un changement pour le chargeur car le pain d'épices. J'ai utilisé cette méthode sur un Nexus One avec les deux Froyo et Gingerbread et cela semble être la seule méthode pour le faire fonctionner.
OriginalL'auteur ldav1s
Veuillez essayez de suivre les lignes directrices que j'ai fournis pour le problème que vous référant au début de votre question (je veux dire ici). Bonne chance!
Je n'ai pas vu ce genre d'erreur dans mes bibliothèques. Après quelques recherches j'ai trouvé que ce réadressage de type 3 est R_ARM_REL32 défini à l'elfe.h. J'ai regardé sur google et ce dans cette conversation est sorti: groups.google.com/group/android-ndk/browse_thread/thread/... Il mentionne que R_ARM_REL32 n'est pas valide d'un déménagement dans la dynamique des exécutables. Je ne suis pas un C/C++ expert donc je ne peux pas vous aider, avec exactement le explenation, mais peut-être cela va vous en dire plus, puis il me dit.
Maciej peut-être quelque chose. Comment le fait de faire une simple bibliothèque (une copie renommée de libhello-jni?) et d'essayer de le charger via la même méthode. Ensuite, essayez de faire couper les versions de votre bibliothèque.
OriginalL'auteur Maciej Pigulski
Ok, je n'ai jamais utilisé Android avant, de sorte que sa peut être un commentaire stupide, mais en JavaSE il ne fonctionne pas trop, parce que votre fichier de bibliothèque est "mauvais".
Voir, vous écrivez un programme en java, donc vous ne savez pas de quelle SORTE il sera exécuté, non? Comment pouvez-vous savoir si la lib que vous souhaitez charger est dans le fichier myLib.ou myLib.dll ou myLib.32TestNotHackerSufix?
Eh bien... vous n'avez pas! C'est de java! Il permettra de résoudre le suxe supplémentaire de la lib pour vous en fonction de votre.
Essayez d'utiliser
sans ".".
(Je suppose que vous n'avez pas quelque chose comme "LIBRARY_PATH" dans Android, il vous permettra de charger vos lib à partir du chemin d'accès que vous lui dites.... Si une telle chose existe dans Android, vous shoul charge votre lib comme
et de mettre votre répertoire dans LIBRARY_PATH avant de démarrer votre application)
OriginalL'auteur Plínio Pantaleão