java Android - 加载库失败
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/3631201/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Android - failure on loading library
提问by I82Much
I have a similar problem to this question, but slightly different. I have compiled a .so library to use with JNI. Because it is large (15 MB), I am putting it on the SDCard instead of in the standard application place.
我有一个与此问题类似的问题,但略有不同。我编译了一个 .so 库以与 JNI 一起使用。因为它很大(15 MB),所以我把它放在 SDCard 上而不是放在标准的应用程序位置。
The file is called libSample.so and it's located at /data/library/libSample.so
该文件名为 libSample.so,位于 /data/library/libSample.so
I load it in a static initialization block:
我将它加载到静态初始化块中:
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());
}
Here's the relevant logcat output:
这是相关的 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
Any idea what's wrong?
知道出了什么问题吗?
I read the post about can android load dll's from sdcard in native modewhich said that the sdcard cannot be used to load libraries, so I moved the .so into /data/data/com.example.hellojni/lib/libSample.so (the private app data storage location). No change:
我阅读了关于android 是否可以在本机模式下从 sdcard 加载 dll 的帖子,其中说 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
What I don't understand is that clearly the library exists, and the OS is trying to load it ... so what would make it fail?
我不明白的是,库显然存在,并且操作系统正在尝试加载它......那么什么会导致它失败?
Following the advice of one of the commentors, I tried attaching via strace to get more detailed error information. The log can be found as a github gist.
按照其中一位评论者的建议,我尝试通过 strace 附加以获得更详细的错误信息。该日志可以作为github gist找到。
The error appears to be on lines 47-51:
错误似乎在第 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
Here's the readelf of the library:
这是图书馆的readelf:
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
回答by Paul Gregtheitroade
I think it may be more likely that a library that your .so depends upon is not being found. But that is only if .so files can be loaded from an SDCard in the first place.
我认为更有可能找不到您的 .so 所依赖的库。但前提是 .so 文件可以首先从 SDCard 加载。
回答by ldav1s
Does libSample.so
have any dependencies on other shared libs that you may be building? If so, you'll need to System.loadLibrary
or System.load
its dependencies first, making sure to load the most "basic" libraries before others, as if they were static libs. At least it seems to be this way with NDK 7b.
是否libSample.so
对您可能正在构建的其他共享库有任何依赖?如果是这样,您需要首先System.loadLibrary
或System.load
它的依赖项,确保在其他库之前加载最“基本”的库,就好像它们是静态库一样。至少 NDK 7b 似乎是这样。
For example, if libSample.so
depends on libfoo.so
you should do something like:
例如,如果libSample.so
取决于libfoo.so
您应该执行以下操作:
System.loadLibrary("foo");
System.loadLibrary("Sample");
回答by Maciej Pigulski
回答by Plínio Pantale?o
Ok, i never used Android before, so its may be a stupid comment, but in JavaSE it will not work too, because your library file is "wrong". See, you write a program in java, so you dont know in what SO it will run, right? How could you know if the lib you want to load is in file myLib.so or myLib.dll or myLib.32TestNotHackerSufix? Well... you dont! It's java! It will solve the sufix of the lib for you based on your SO.
好吧,我以前从未使用过 Android,所以它可能是一个愚蠢的评论,但在 JavaSE 中它也不起作用,因为您的库文件是“错误的”。看,你用java写了一个程序,所以你不知道它会在什么地方运行,对吧?你怎么知道你要加载的库是在文件 myLib.so 还是 myLib.dll 或 myLib.32TestNotHackerSufix 中?嗯……你没有!是爪哇!它将根据您的 SO 为您解决 lib 的后缀。
Try use
尝试使用
File libraryLoc = new File(sdcard.getAbsolutePath() + "/library/libSample");
without ".so".
没有“.so”。
(I suppose you dont have something like "LIBRARY_PATH" in Android, so it will load your lib from the path you tell him.... If such thing exists in Android you shoul load your lib like
(我想你在Android中没有像“LIBRARY_PATH”这样的东西,所以它会从你告诉他的路径加载你的lib......如果Android中存在这样的东西,你应该加载你的lib
System.load("libSampe");
and put your directory in LIBRARY_PATH before start your app)
并在启动您的应用程序之前将您的目录放在 LIBRARY_PATH 中)