Android NDK 无法加载 libc++_shared.so,获取“无法定位符号 'rand' 参考

Android NDK cannot load libc++_shared.so, gets "cannot locate symbol 'rand' reference

在我的 java class 我有这个:

static
{
    System.loadLibrary("c++_shared");

    System.loadLibrary("com.testandroid.LibAndroidBridge");
}

我的 Application.mk 有这个:

NDK_TOOLCHAIN_VERSION:=4.8
APP_STL := c++_shared
APP_ABI := x86

一切正常,但是当我 运行 应用程序(在模拟器或设备上,所以 x85 和 arm)时,我在 LogCat:

中得到了这个
02-13 12:00:32.174: D/dalvikvm(2142): Trying to load lib /data/app-lib/com.testandroid-1/libc++_shared.so 0xb0fcfc60
02-13 12:00:32.174: D/dalvikvm(2142): Added shared lib /data/app-lib/com.testandroid-1/libc++_shared.so 0xb0fcfc60
02-13 12:00:32.174: D/dalvikvm(2142): No JNI_OnLoad found in /data/app-lib/com.testandroid-1/libc++_shared.so 0xb0fcfc60, skipping init
02-13 12:00:32.174: D/dalvikvm(2142): Trying to load lib /data/app-lib/com.testandroid-1/libcom.testandroid.LibAndroidBridge.so 0xb0fcfc60
02-13 12:00:32.174: E/dalvikvm(2142): dlopen("/data/app-lib/com.testandroid-1/libcom.testandroid.LibAndroidBridge.so") failed: dlopen failed: cannot locate symbol "rand" referenced by "libcom.testandroid.LibAndroidBridge.so"...
02-13 12:00:32.174: W/dalvikvm(2142): Exception Ljava/lang/UnsatisfiedLinkError; thrown while initializing Lcom/testandroid/AriesLib;
02-13 12:00:32.174: D/AndroidRuntime(2142): Shutting down VM
02-13 12:00:32.174: W/dalvikvm(2142): threadid=1: thread exiting with uncaught exception (group=0xb0cb0b20)
02-13 12:00:32.174: E/AndroidRuntime(2142): FATAL EXCEPTION: main
02-13 12:00:32.174: E/AndroidRuntime(2142): Process: com.testandroid, PID: 2142
02-13 12:00:32.174: E/AndroidRuntime(2142): java.lang.UnsatisfiedLinkError: dlopen failed: cannot locate symbol "rand" referenced by "libcom.testandroid.LibAndroidBridge.so"...
02-13 12:00:32.174: E/AndroidRuntime(2142):     at java.lang.Runtime.loadLibrary(Runtime.java:364)

有人知道为什么无法导入 c++_shared.so 库吗?​​

问题完全出在原生端。 Java 对 JNI 边界之后发生的事情一无所知。您不能让两个本机库以这种方式运行。特别是 C++ 标准库(它没有任何符号可以被 JNI 轻松可靠地访问)。

您应该解析本机端的所有符号,即您应该正确地 link C++ 标准库到您的 libcom.testandroid.LibAndroidBridge.so

我建议不要在 Android 上混合使用 {gcc 工具链(在您的情况下为 4.8)+ libc++("c++_shared")} 或 {clang + libstdc++}。理论上它应该可以在桌面 Linux 或 OSX 上运行,但仍然存在可移植性问题,并且在 Android 上仍然存在一些怪癖,具体取决于 NDK 版本、目标和一些 "random" 因素.所以它并不总是有效。

很遗憾,您没有提供您正在使用的代码 rand(甚至可能是非标准库 rand,而是一些自定义代码?),但您仍然可以尝试:

  • 使用 GCC 的 GNU 标准库,将 GCC 4.8 作为工具链

  • 使用 Clang 编译器,将 libc++ 保留为标准库

AND/OR

  • 对 "debugging purposes" 使用静态 linking(它不会 link 直到丢失某些东西,让你找到原因而不用弄乱 Java 和JNI)

真正的错误是其他原因:rand() 不存在,因为 Android-21 不兼容。

java.lang.UnsatisfiedLinkError: dlopen failed: cannot locate symbol "rand" referenced by

查看此thread了解更多信息。

建议的修复方法是在 jni/Application.mk 中降级 API 并将其设置为 低于 Android-21。 如果您需要 Android-21,那么 Google 实际上建议发送多个 APK 文件。呃.

你不必写

System.loadLibrary("c++_shared");

只需包括:-

APP_STL := c++_shared 

在你的 Application.mk 这应该使它工作,现在 libc++_shared.so 将被捆绑