链接共享库libGLES_mali.so会导致dlopen失败:在Android> = 7.0中找不到库“android.hardware…@1.0.so”

Android 7.0开始,不再可能链接到非ndk共享库(参见NDK Apps Linking to Platform Libraries).

一种可能的解决方法是将库包含在apk中(参见Update your app).

您尝试链接的库可能依赖于其他非ndk库.在这种情况下,您也应该包括这些库.

就我而言,我一直在开发一个使用OpenCL的应用程序.在ARM设备上,具有正确符号的库是libGLES_mali.so.该应用程序适用于Android< 7.0但它在Android> = 7.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.common@1.0.so就是其中之一:

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的一部分(见SP-HAL),因此我理解私有库可以*地依赖它.

有什么建议吗?

编辑31/01/2019:在Android> = 7.0上运行的经过测试的设备都是华为.它可能是供应商相关的问题吗?

解决方法:

Alex Cohn评论是对的.为了解决这个问题,我做了以下几点:

1)在libfoo.so中重命名为android.hardware.graphics.common@1.0.so

2)在CMakeLists.txt中添加了libfoo.so,如下所示:

add_library( foo
         SHARED
         IMPORTED )
set_target_properties( foo
         PROPERTIES IMPORTED_LOCATION
         ${PROJECT_SOURCE_DIR}/src/main/jniLibs/${ANDROID_ABI}/libfoo.so )

3)针对libfoo.so的目标链接MyLibrary,其中包含OpenCL调用(当然,还有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 /文件夹复制到文件夹${PROJECT_SOURCE_DIR} / src / main / jniLibs / ${ANDROID_ABI} /,其中libfoo.so是.

5)最后,和以前一样,我在需要时加载了MyLibrary.

应用程序不再崩溃并按预期工作.非常感谢!

上一篇:SAP请求释放怎么撤回


下一篇:自己总结JS