无法使用 System.loadLibrary 找到 Android 的 GNU STL 共享库

标签 android stl android-ndk

我已经使用 android-cmake 和 NDK 针对 libstdc++ 编译了一个共享库,并且根据 android-ndk-r7/docs/CPLUSPLUS-SUPPORT.html,我试图在加载我的库之前加载 gnuSTL_shared:

static {
    System.loadLibrary("gnustl_shared");
    System.loadLibrary("MathTest");
}

我可以看到这正在完成,例如 here但我得到一个异常(exception):

01-03 20:02:42.307: E/AndroidRuntime(569): Caused by: java.lang.UnsatisfiedLinkError: Couldn't load gnustl_shared: findLibrary returned null

如果我不加载 gnuSTL_shared,它将失败并出现以下异常:

01-03 20:03:04.667: E/AndroidRuntime(603): Caused by: java.lang.UnsatisfiedLinkError: Cannot load library: reloc_library[1311]:    33 cannot locate '_ZNSo3putEc'...

我在 API 级别 8 和 9 上测试过同样的问题。我究竟做错了什么?我假设它在最后一个异常中寻找的符号与 STL 相关,并且加载它可以解决问题。是这样吗?

编辑: 我现在已经按照答案的建议包含了 STL 库。 CMake 生成的编译行是这样的(请注意,我的项目有三个文件,mother.c(George Marsaliga 的 Mother of All Random Number Generator 的副本可用 here),Driver. cpp 包含测试不同数学库的函数并打印出函数运行时,androidactivity.cpp 包含 JNI 胶水并从 Driver.cpp。CMake 生成的详细 Makefile 输出如下。我不确定这是否是有用的信息,但是

[ 33%] Building CXX object CMakeFiles/MathTest.dir/src/Driver.cpp.o
/Users/martin/Android/android-ndk-r7/toolchains/arm-linux-androideabi-4.4.3/prebuilt/darwin-x86/bin/arm-linux-androideabi-g++   -DMathTest_EXPORTS -D__STDC_INT64__ --sysroot=/Users/martin/Android/android-ndk-r7/platforms/android-8/arch-arm -fPIC -DANDROID -Wno-psabi -fsigned-char -mthumb -Wnon-virtual-dtor -Wno-long-long -ansi -Wundef -Wcast-align -Wchar-subscripts -Wall -W -Wpointer-arith -Wwrite-strings -Wformat-security -fexceptions -fno-check-new -fno-common -fstrict-aliasing -Wno-variadic-macros -Wextra -pedantic -g0 -O2 -fPIC -isystem /Users/martin/Android/android-ndk-r7/sources/cxx-stl/gnu-libstdc++/include -isystem /Users/martin/Android/android-ndk-r7/sources/cxx-stl/gnu-libstdc++/libs/armeabi/include -I/Users/martin/Repositories/MathTest/lib/cml-1_0_2 -I/Users/martin/Repositories/MathTest/lib/eigen-eigen-13a11181fc5a -I/Users/martin/Repositories/MathTest/lib/glm-0.9.3.B   -o CMakeFiles/MathTest.dir/src/Driver.cpp.o -c /Users/martin/Repositories/MathTest/src/Driver.cpp
"/Applications/CMake 2.8-4.app/Contents/bin/cmake" -E cmake_progress_report /Users/martin/Repositories/MathTest/build/android/CMakeFiles 2
[ 66%] Building C object CMakeFiles/MathTest.dir/src/mother.c.o
/Users/martin/Android/android-ndk-r7/toolchains/arm-linux-androideabi-4.4.3/prebuilt/darwin-x86/bin/arm-linux-androideabi-gcc  -DMathTest_EXPORTS -D__STDC_INT64__ --sysroot=/Users/martin/Android/android-ndk-r7/platforms/android-8/arch-arm -fPIC -DANDROID -Wno-psabi -fsigned-char -mthumb -O3 -DNDEBUG -fPIC -I/Users/martin/Android/android-ndk-r7/sources/cxx-stl/gnu-libstdc++/include -I/Users/martin/Android/android-ndk-r7/sources/cxx-stl/gnu-libstdc++/libs/armeabi/include -I/Users/martin/Repositories/MathTest/lib/cml-1_0_2 -I/Users/martin/Repositories/MathTest/lib/eigen-eigen-13a11181fc5a -I/Users/martin/Repositories/MathTest/lib/glm-0.9.3.B   -o CMakeFiles/MathTest.dir/src/mother.c.o   -c /Users/martin/Repositories/MathTest/src/mother.c
"/Applications/CMake 2.8-4.app/Contents/bin/cmake" -E cmake_progress_report /Users/martin/Repositories/MathTest/build/android/CMakeFiles 3
[100%] Building CXX object CMakeFiles/MathTest.dir/src/androidactivity.cpp.o
/Users/martin/Android/android-ndk-r7/toolchains/arm-linux-androideabi-4.4.3/prebuilt/darwin-x86/bin/arm-linux-androideabi-g++   -DMathTest_EXPORTS -D__STDC_INT64__ --sysroot=/Users/martin/Android/android-ndk-r7/platforms/android-8/arch-arm -fPIC -DANDROID -Wno-psabi -fsigned-char -mthumb -Wnon-virtual-dtor -Wno-long-long -ansi -Wundef -Wcast-align -Wchar-subscripts -Wall -W -Wpointer-arith -Wwrite-strings -Wformat-security -fexceptions -fno-check-new -fno-common -fstrict-aliasing -Wno-variadic-macros -Wextra -pedantic -g0 -O2 -fPIC -isystem /Users/martin/Android/android-ndk-r7/sources/cxx-stl/gnu-libstdc++/include -isystem /Users/martin/Android/android-ndk-r7/sources/cxx-stl/gnu-libstdc++/libs/armeabi/include -I/Users/martin/Repositories/MathTest/lib/cml-1_0_2 -I/Users/martin/Repositories/MathTest/lib/eigen-eigen-13a11181fc5a -I/Users/martin/Repositories/MathTest/lib/glm-0.9.3.B   -o CMakeFiles/MathTest.dir/src/androidactivity.cpp.o -c /Users/martin/Repositories/MathTest/src/androidactivity.cpp
Linking CXX shared library ../../android/libs/armeabi/libMathTest.so

readelf 显示我的库依赖于 libstdc++libmlibclibdl,据我所知,除了 libstdc++ 之外,所有这些都可以根据 android-ndk-r7/docs/STABLE-APIS.html 在设备上使用。

Martin-Foots-MacBook-Pro:android martin$ ~/Android/android-ndk-r7/toolchains/arm-linux-androideabi-4.4.3/prebuilt/darwin-x86/bin/arm-linux-androideabi-readelf -d ../../android/libs/armeabi/libMathTest.so 

Dynamic section at offset 0x14b0 contains 25 entries:
  Tag        Type                         Name/Value
 0x00000001 (NEEDED)                     Shared library: [libstdc++.so]
 0x00000001 (NEEDED)                     Shared library: [libm.so]
 0x00000001 (NEEDED)                     Shared library: [libc.so]
 0x00000001 (NEEDED)                     Shared library: [libdl.so]
 0x0000000e (SONAME)                     Library soname: [libMathTest.so]
 0x00000010 (SYMBOLIC)                   0x0
 0x00000019 (INIT_ARRAY)                 0x9498
 0x0000001b (INIT_ARRAYSZ)               12 (bytes)
 0x0000001a (FINI_ARRAY)                 0x94a4
 0x0000001c (FINI_ARRAYSZ)               12 (bytes)
 0x00000004 (HASH)                       0xd4
 0x00000005 (STRTAB)                     0x544
 0x00000006 (SYMTAB)                     0x234
 0x0000000a (STRSZ)                      1033 (bytes)
 0x0000000b (SYMENT)                     16 (bytes)
 0x00000003 (PLTGOT)                     0x9598
 0x00000002 (PLTRELSZ)                   136 (bytes)
 0x00000014 (PLTREL)                     REL
 0x00000017 (JMPREL)                     0x990
 0x00000011 (REL)                        0x950
 0x00000012 (RELSZ)                      64 (bytes)
 0x00000013 (RELENT)                     8 (bytes)
 0x00000016 (TEXTREL)                    0x0
 0x6ffffffa (RELCOUNT)                   4
 0x00000000 (NULL)                       0x0    

这些信息有帮助吗?有什么方法可以告诉我未找到的符号来自哪里?

最佳答案

好吧,你需要在你自己的库之前加载 gnuSTL_shared,像这样:

static {
    System.loadLibrary("gnustl_shared");
    System.loadLibrary("myNativeLib1");
    System.loadLibrary("myNativeLib2");
    //.......
}

关于无法使用 System.loadLibrary 找到 Android 的 GNU STL 共享库,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/8717986/

相关文章:

android - 新行的损坏插入 ID

android - 使用 NDK 时 Unresolved inclusion 错误

c++ - Visual Studio C++ intellisense 函数信息 - 如何解释各种分隔符、类型和首字母缩略词

c++ - 算法 - 具有最近路径前缀回退的查找树

java - 通过 MAT 了解内存泄漏

android - QT Widget 使用 OpenCV 错误部署到 Android

Android Edittext 仅编号

java - E/AndroidRuntime : FATAL EXCEPTION: main at dalvik. system.NativeStart.main(Native Method) 崩溃

php - 在移动服务器通信中使用密码作为加密 key 的一部分

传递 container.start() 和 container.end() 的 C++ 更简洁的替代方法