【问题标题】:java.lang.UnsatisfiedLinkError: dlopen failed: cannot locate symbol "_ZNSt6__ndk17codecvtIcc9mbstate_tE2idE"java.lang.UnsatisfiedLinkError:dlopen 失败:找不到符号“_ZNSt6__ndk17codecvtIcc9mbstate_tE2idE”
【发布时间】:2017-11-01 03:12:19
【问题描述】:

我使用ndk-build构建静态库并成功编译为*.so,但在android模拟器中运行时抛出运行时错误。错误是

E/AndroidRuntime: FATAL EXCEPTION: main
                  Process: org.example.kotlin.mixed, PID: 31185
                  java.lang.UnsatisfiedLinkError: dlopen failed: cannot locate symbol "_ZNSt6__ndk17codecvtIcc9mbstate_tE2idE" referenced by "/data/app/org.example.kotlin.mixed-2/lib/x86/libtest.so"...
                      at java.lang.Runtime.loadLibrary(Runtime.java:372)
                      at java.lang.System.loadLibrary(System.java:1076)
                      at com.bytedance.lark.sdk.Sdk.<init>(Sdk.kt:15)
                      at org.example.kotlin.mixed.MyApplication.onCreate(MyApplication.kt:12)
                      at android.app.Instrumentation.callApplicationOnCreate(Instrumentation.java:1013)
                      at android.app.ActivityThread.handleBindApplication(ActivityThread.java:4707)
                      at android.app.ActivityThread.-wrap1(ActivityThread.java)
                      at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1405)
                      at android.os.Handler.dispatchMessage(Handler.java:102)
                      at android.os.Looper.loop(Looper.java:148)
                      at android.app.ActivityThread.main(ActivityThread.java:5417)
                      at java.lang.reflect.Method.invoke(Native Method)
                      at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:726)
                      at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:616)

我发现符号 _ZNSt6__ndk17codecvtIcc9mbstate_tE2idE 出现在我构建的静态库中。我在我的源代码中找不到 ndk 的参考。我不确定 ndk-build 是否将此符号添加到静态库中。

ndk-build 配置放在这里。

应用程序.mk

APP_ABI := x86

APP_PLATFORM := android-21 // I change this to android-14, also not work
APP_STL:=c++_static
APP_CPPFLAGS:=-std=c++11 -fexceptions -frtti  -DANDROID -DDEBUG

NDK_TOOLCHAIN_VERSION := clang

Android.mk

LOCAL_PATH := $(call my-dir)

include $(CLEAR_VARS)

include ../uuid/Android.mk
include mylib.mk

mylib.mk

LOCAL_PATH := $(call my-dir)

MYLIB_CSOURCES := \
  // my source code

MYLIB_INCLUDES := \
  $(LOCAL_PATH)/../uuid/include \
  $(LOCAL_PATH)/../../../../../lib/rapidjson/include \
  $(LOCAL_PATH)/../../../../../src

###
### Build mylib.a
###

include $(CLEAR_VARS)

LOCAL_MODULE := mylibc++

LOCAL_SRC_FILES := \
    $(addprefix ../../../../../src/,$(MYLIB_CSOURCES))

LOCAL_C_INCLUDES := $(MYLIB_INCLUDES)

LOCAL_CFLAGS += -DANDROID -DDEBUG -D__ANDROID__

LOCAL_WHOLE_STATIC_LIBRARIES := uuid

include $(BUILD_STATIC_LIBRARY)

android 构建配置:

android {
    compileSdkVersion 23
    buildToolsVersion '26.0.2'

    defaultConfig {
        minSdkVersion 14
        targetSdkVersion 23
        versionCode 1
        versionName "1.0"
    }
    lintOptions {
        abortOnError false
    }
    sourceSets.main {
        jni.srcDirs = []
        jniLibs.srcDir 'libs'
    }
}

【问题讨论】:

  • 在您的应用程序中,您加载 libtest.so。但是这个库是如何构建的呢?它使用 libmylibc++.a 吗?
  • 我在我的 RUST 项目中使用 libmylibc++.a 来构建 libtest.so。如果我删除 libmylibc++.a,应用程序运行良好,但如果我在 libtest.so 中添加 libmylibc++.a,应用程序会抛出如前所述的 RuntimeError。如果我使用nm 命令,符号_ZNSt6__ndk17codecvtIcc9mbstate_tE2idE 会出现在libmylibc++.a 中。
  • 顺便说一句,NDK 会为您设置-DANDROID -DDEBUG -D__ANDROID__,您无需将其添加到 LOCAL_CFLAGS

标签: android android-ndk


【解决方案1】:

_ZNSt6__ndk17codecvtIcc9mbstate_tE2idE 符号(表示 std::__ndk1::codecvt::id)在 libc++_shared.so 中可用.

如果您的运行时环境(模拟器)低于 API 21,您必须在加载 libtest.so 之前从 Java 显式加载此库强>.

libc++_shared.so 也应与 libtest.so 一起打包到 APK 中。确保它存在于 libs/x86 以及其他相关 ABI 中。

在 Android Studio 中,您可以让 gradle 为您构建 NDK 库,它会处理必要的依赖项。

【讨论】:

  • 将libc++_shared.so添加到android项目后,应用运行良好,谢谢!
  • 这并不能解释为什么它不能与 c++_static 一起使用。大概 libmylibc++.a 被用于其他没有链接 c++_static 的构建中?
  • @DanAlbert 我猜你是对的,libmylibc++.a 应该使用APP_STL=c++_shared 构建,但幸运的是对于静态库来说这没有什么区别。我不知道如何强制 RUST 选择 STL 库,所以最好使用任何可行的方法。
  • 从哪里可以得到 libc++_shared.so 文件?
  • @Innocent 它被打包在 Android NDK 中
猜你喜欢
  • 2017-10-13
  • 1970-01-01
  • 2016-11-15
  • 2017-02-19
  • 2017-02-19
  • 1970-01-01
  • 2019-02-04
  • 2017-04-11
  • 2019-07-31
相关资源
最近更新 更多