Android – 加载库失败

我对这个问题有类似的问题,但稍有不同。 我编译了一个.so库来和JNI一起使用。 因为它很大(15 MB),所以我把它放在SD卡上,而不是在标准的应用程序中。

该文件被称为libSample.so,它位于/data/library/libSample.so

我加载它在一个静态的初始化块:

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

这里是相关的logcat输出:

 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 

任何想法有什么不对?

我读了关于可以从本地模式的SD卡加载dll的post,说sdcard不能用于加载库,所以我把.so移动到/data/data/com.example.hellojni/lib/libSample.so(私人应用程序数据存储位置)。 不用找了:

 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 

我不明白的是,图书馆显然存在,而操作系统正在试图加载它…所以什么会使它失败?

根据其中一位评论者的build议,我尝试通过strace附加获得更详细的错误信息。 日志可以被find作为github主要 。

错误似乎在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 

这里是图书馆的重build:

 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 

Solutions Collecting From Web of "Android – 加载库失败"

我认为你的.so所依赖的图书馆可能更有可能没有find。 但是,这只是如果.so文件可以从一个SD卡首先加载。

libSample.so是否对您可能正在构build的其他共享库有依赖关系? 如果是这样的话,你首先需要System.loadLibrary或者System.load它的依赖关系,确保将最基本的库加载到别人之前,就好像它们是静态库一样。 NDK 7b似乎至less这样。

例如,如果libSample.so依赖于libfoo.so你应该这样做:

 System.loadLibrary("foo"); System.loadLibrary("Sample"); 

请尝试以下指导原则,我已经提供了您在问题开始时提到的问题(我的意思是这里 )。 祝你好运!

好吧,我从来没有使用过Android,所以它可能是一个愚蠢的评论,但在JavaSE中,它不会工作,因为你的库文件是“错误的”。 看,你用java写一个程序,所以你不知道它会运行什么,对吧? 你怎么能知道你要加载的库在文件myLib.so或myLib.dll或myLib.32TestNotHackerSufix? 那么…你不要! 这是Java! 它会根据你的SO来解决lib的sufix问题。

尝试使用

  File libraryLoc = new File(sdcard.getAbsolutePath() + "/library/libSample"); 

没有“.so”。

(我想你在Android中没有像“LIBRARY_PATH”的东西,所以它会从你告诉他的path加载你的lib ….如果这样的东西存在于Android中,你可以像加载你的lib一样

 System.load("libSampe"); 

并在启动您的应用程序之前将您的目录放在LIBRARY_PATH中)