首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >链接共享库libGLES_mali.so导致dlopen失败:在>= 7.0中找不到库“android.hard.@1.0.so”

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

Stack Overflow用户
提问于 2019-01-30 10:36:56
回答 2查看 2.2K关注 0票数 4

自从Android7.0之后,就不可能再链接到非ndk共享库了(参见NDK应用程序链接到平台库)。

一个可能的解决方法是将库包含在apk中(请参阅更新应用程序)。

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

在我的例子中,我一直在开发一个使用OpenCL的应用程序。在ARM设备上,具有正确符号的库是libGLES_mali.so。该应用程序在Android < 7.0的设备上运行良好,但它在使用Android7.0的设备上崩溃。我可以在logcat中读取的错误是:

代码语言:javascript
复制
java.lang.UnsatisfiedLinkError: dlopen failed: library "android.hardware.graphics.common@1.0.so" not found

使用命令

代码语言:javascript
复制
readelf -d libGLES_mali.so | grep NEEDED

我可以读取libGLES_mali.so所依赖的库的名称,并且可以预见,android.hardware.Graphics.public@1.0也是其中之一:

代码语言:javascript
复制
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上的测试设备都是华为。这可能是与供应商有关的问题吗?

EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2019-02-01 09:31:35

亚历克斯·科恩的评论是对的。为了解决这个问题,我做了以下工作:

1)在libfoo.so中改名为android.hardware.Graphics.public@1.0.so

2)在libfoo.so中添加了这样的CMakeLists.txt:

代码语言:javascript
复制
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)

代码语言:javascript
复制
target_link_libraries (MyLibrary GLES_mali foo)

4)尽快加载libfoo.so。为此,我在MainActivity中创建了一个静态方法,应用程序一进入onCreate()就调用该方法。

代码语言:javascript
复制
private static void loadLibrary() {
    System.loadLibrary("foo");
}

@Override
protected void onCreate(Bundle savedInstanceState) {
    loadLibrary();
    ...
}  

此时,应用程序崩溃,抱怨找不到一些库。使用readelf命令:

代码语言:javascript
复制
./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。

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

票数 3
EN

Stack Overflow用户

发布于 2020-03-07 09:09:27

在libOpenCL.so库需要libcutils.so的情况下,我遇到了类似的问题,我以稍微不同的方式解决了这个问题:

我没有在.apk中链接和包含.apk,而是选择只将c++代码链接到它,然后使用在电话上本地安装的库libOpenCL.so (它是同一个文件--不需要在两个不同的位置拥有它)。

这对我来说要容易得多,因为通过这样做,我不必在我的应用一启动就重新命名和加载libcutils (我有SW的设计限制,阻止了我这么做)。

以下是详细信息:

  1. 我在Android打包.apk文件时不包括的位置创建了一个lib dir (ex: src/cpp/lib)
  2. 我用“亚行拉”从手机上下载了32位和64位的libOpenCL.so .并将它们分别保存到src/cpp/lib/armeabi-v7a和src/cpp/lib/arm64-v8a (我想您做了一件类似的事情--参见安卓支持OpenCL吗?获得更多详细信息)。
  3. 我在我的CMakeKists.txt中添加了以下两行:
代码语言:javascript
复制
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被不同的称呼,在不同的手机上处于不同的位置)。请告诉我,如果你知道这样做的方法:)

票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/54438558

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档