自从Android7.0之后,就不可能再链接到非ndk共享库了(参见NDK应用程序链接到平台库)。
一个可能的解决方法是将库包含在apk中(请参阅更新应用程序)。
您要链接的库可能依赖于其他非ndk库。在这种情况下,您也应该包括那些库。
在我的例子中,我一直在开发一个使用OpenCL的应用程序。在ARM设备上,具有正确符号的库是libGLES_mali.so。该应用程序在Android < 7.0的设备上运行良好,但它在使用Android7.0的设备上崩溃。我可以在logcat中读取的错误是:
java.lang.UnsatisfiedLinkError: dlopen failed: library "android.hardware.graphics.common@1.0.so" not found使用命令
readelf -d libGLES_mali.so | grep NEEDED我可以读取libGLES_mali.so所依赖的库的名称,并且可以预见,android.hardware.Graphics.public@1.0也是其中之一:
0x0000000000000001 (NEEDED) Shared library: [android.hardware.graphics.common@1.0.so]
0x0000000000000001 (NEEDED) Shared library: [liblog.so]
0x0000000000000001 (NEEDED) Shared library: [libnativewindow.so]
0x0000000000000001 (NEEDED) Shared library: [libz.so]
0x0000000000000001 (NEEDED) Shared library: [libc++.so]
0x0000000000000001 (NEEDED) Shared library: [libutils.so]
0x0000000000000001 (NEEDED) Shared library: [libcutils.so]
0x0000000000000001 (NEEDED) Shared library: [libm.so]
0x0000000000000001 (NEEDED) Shared library: [libc.so]
0x0000000000000001 (NEEDED) Shared library: [libdl.so]我尝试过将前面提到的库包含在apk中,但是我得到了同样的错误。奇怪的是,库是VNDK(参见SP-HAL)的一部分,因此,我的理解是,私有库可以自由地依赖它。
有什么建议吗?
编辑31/01/2019:运行在安卓>= 7.0上的测试设备都是华为。这可能是与供应商有关的问题吗?
发布于 2019-02-01 09:31:35
亚历克斯·科恩的评论是对的。为了解决这个问题,我做了以下工作:
1)在libfoo.so中改名为android.hardware.Graphics.public@1.0.so
2)在libfoo.so中添加了这样的CMakeLists.txt:
add_library( foo
SHARED
IMPORTED )
set_target_properties( foo
PROPERTIES IMPORTED_LOCATION
${PROJECT_SOURCE_DIR}/src/main/jniLibs/${ANDROID_ABI}/libfoo.so )3)目标链接MyLibrary,它包含OpenCL调用,针对libfoo.so (当然还有libGLES_mali.so)
target_link_libraries (MyLibrary GLES_mali foo)4)尽快加载libfoo.so。为此,我在MainActivity中创建了一个静态方法,应用程序一进入onCreate()就调用该方法。
private static void loadLibrary() {
System.loadLibrary("foo");
}
@Override
protected void onCreate(Bundle savedInstanceState) {
loadLibrary();
...
} 此时,应用程序崩溃,抱怨找不到一些库。使用readelf命令:
./readelf -d /Users/rodolforocco/AndroidProjects/OvermindClient/app/libs/arm64-v8a/android-27/libfoo.so | grep NEEDED我能够看到这些确实是libfoo.so所依赖的库。这些库还依赖于无法定位的其他库。我将它们全部从设备中的文件夹/system/lib64 64/复制到${PROJECT_SOURCE_DIR}/src/main/jniLibs/${ANDROID_ABI}/,文件夹libfoo.so所在的位置。
5)最后,和以前一样,我在需要时加载了MyLibrary。
该应用程序不再崩溃,并按预期工作。非常感谢!
发布于 2020-03-07 09:09:27
在libOpenCL.so库需要libcutils.so的情况下,我遇到了类似的问题,我以稍微不同的方式解决了这个问题:
我没有在.apk中链接和包含.apk,而是选择只将c++代码链接到它,然后使用在电话上本地安装的库libOpenCL.so (它是同一个文件--不需要在两个不同的位置拥有它)。
这对我来说要容易得多,因为通过这样做,我不必在我的应用一启动就重新命名和加载libcutils (我有SW的设计限制,阻止了我这么做)。
以下是详细信息:
add_library(OpenCL SHARED IMPORTED)
set_target_properties(OpenCL PROPERTIES IMPORTED_LOCATION ${CMAKE_SOURCE_DIR}/src/main/cpp/lib/${ANDROID_ABI}/libOpenCL.so)这有点悲哀,但在我看来,几乎不可能让OpenCL应用程序在所有的安卓手机上工作( libs被不同的称呼,在不同的手机上处于不同的位置)。请告诉我,如果你知道这样做的方法:)
https://stackoverflow.com/questions/54438558
复制相似问题