在运行时加载多个共享库在Android中不起作用

Bre*_*ley 6 java-native-interface android cmake shared-libraries

我正在使用cmake在Android Studio中创建我的共享库.库正确构建和链接,我能够在lib/armeabi-v7a下的Apk中看到我的所有库.

这些库链接如下:

  • LIB1
    • LIB2
      • LIB3
        • LIB4
        • Lib5

我通过拨打电话来加载我的Lib1 System.loadLibrary("lib1");

我能够拨打电话到LIB1,但只要LIB1试图访问LIB2,我得到未加载传播的消息说LIB2.

然后我想我必须加载其他库,所以我做了以下调用但最终得到了相同的传播消息"Lib2 not loaded".

System.loadLibrary("lib5");
System.loadLibrary("lib4");
System.loadLibrary("lib3");
System.loadLibrary("lib2");
System.loadLibrary("lib1");
Run Code Online (Sandbox Code Playgroud)

为什么Lib1无法调用Lib2?是否在导致库加载失败的位置解压缩其他共享库?

我想请注意,在切换到使用cmake之前,我已正确加载了libs.我相信我之前手动编译我的库并将它们存储在我的Android Studio项目的/ jniLibs和/ assets目录中,但那是不久之前所以我的内存在细节上并不清楚.

jdo*_*ald 5

由于您的更改似乎正在生效,我猜这并不是像将二进制文件放在错误的位置那样的意外。(我自己有时上传后jniLibs/armeabi-v7a意识到我正在测试依赖于 的 64 位 APK jniLibs/arm64-v8a。或者在 32 位 Android 设备上安装双架构 apk 时反过来。)

我想我们也可以在加载时排除未解析的符号,因为它通常会告诉您这一点adb logcat

我记得过去看到这个问题时通常发现是 lib2 的soname问题。虽然 PC Linux 可以使用类似的东西liblib2.so.1,但 Android 似乎要求所有 sonames 结尾.so

要检查 lib2 上的 soname,请运行readelf -a liblib2.so. 如果它按照我的描述显示不正确,请重做 NDK 构建并确保-Wl,-soname,liblib2.so在链接时添加它。

此外,运行readelf -a liblib1.so并确保其对 liblib2.so 的引用使用新的 soname 例如(NEEDED) Shared Library: [liblib2.so]。您可能还需要重新链接 liblib1.so。

我想指出的是,在切换到使用 cmake 之前,我已经正确加载了库。

我假设 CMake 用于构建的 NDK 阶段,而不是 Java,这可以解释 soname 的变化。

注意:在每个库的给定名称中添加一个额外的“lib”有点令人困惑。如果你使用一个例子,沟通可能会更容易System.loadLibrary("1")System.loadLibrary("2")