【问题标题】:Android NDK cannot load libc++_shared.so, gets "cannot locate symbol 'rand' referenceAndroid NDK 无法加载 libc++_shared.so,获取“无法定位符号 'rand' 引用
【发布时间】:2015-02-13 17:05:29
【问题描述】:

在我的 java 类中,我有这个:

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 库吗?

【问题讨论】:

  • 你为什么要这么做System.loadLibrary("c++_shared");? C++ 标准库是用 C++ 编写的,几乎不包含任何 JNI 可访问的符号。你的具体目标是什么?
  • 我的理解是,为了强制这个库为c++加载,我需要在java代码中作为库加载。
  • 最终目标是摆脱丢失的“rand”符号
  • 4.4.2 以 sdk 19 为目标

标签: android android-ndk


【解决方案1】:

真正的错误是别的: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 文件。呃。

【讨论】:

    【解决方案2】:

    问题完全出在本机方面。 Java 对超出 JNI 边界的情况没有任何线索。你不能让两个本机库以这种方式运行。特别是 C++ 标准库(它没有任何符号可以被 JNI 轻松可靠地访问)。

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

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

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

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

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

    与/或

    • 将静态链接用于“调试目的”(在缺少某些内容之前它不会链接,这样您就可以在不弄乱 Java 和 JNI 的情况下找到原因)

    【讨论】:

    • 很公平。我现在没有在 Java 中导入 c++_shared 库,并且我已经注释掉了 NDK_TOOLCHAIN_VERSION:=4.8。计划是用llvm编译,或者尽可能接近。根据文档 c++_shared 是 LLVM,对吗? rand 被称为 rand();在 C++ 代码中,它来自 stdlib.h 作为 int rand(void);
    • 通过这些更改,我仍然得到 dlopen("/data/app-lib/com.testandroid-1/libcom.testandroid.LibAndroidBridge.so") failed: dlopen failed: cannot locate symbol " rand”被“libcom.testandroid.LibAndroidBridge.so”引用...
    • 是的,libc++ 是 LLVM 项目的一部分,与 Clang 编译器相同。删除 NDK_TOOLCHAIN_VERSION:=4.8 不会有任何改变。 NDK 默认使用 GCC(使用的版本取决于 NDK 版本)。要使用 clang 编译您的库,请使用 NDK_TOOLCHAIN_VERSION := clang。如果它没有帮助,请尝试APP_STL := c++_static 我回答中的第三点。在所有情况下,请在重建之前仔细检查您是否正确清理了所有旧的二进制文件(*.o、*.so、*.a)以及最终的 APK。使用详细的构建输出(-V 选项)来验证您的项目是否使用所需的工具链和库构建。
    • 使用 clang 的问题是我在几个 .c 文件上出现编译错误,而我在工具链 4.8 中没有遇到这些问题。我应该使用 clang 并尝试修复这些编译问题,还是应该保留 4.8 并尝试以其他方式解决这个 rand() 问题?
    • 让我们尝试另一件事:在Application.mk中设置APP_PLATFORM=android-19
    【解决方案3】:

    你不必写

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

    只包括:-

    APP_STL := c++_shared 
    

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

    【讨论】:

    • Android System.loadLibrary("c++_shared")。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2023-03-16
    • 1970-01-01
    • 2013-07-12
    • 2016-05-01
    • 2015-11-12
    • 1970-01-01
    相关资源
    最近更新 更多