AOSP的libc++.so与NDK的libc++_shared.so相同吗?

本教程将介绍AOSP的libc++.so与NDK的libc++_shared.so相同吗?的处理方法,这篇教程是从别的地方看到的,然后加了一些国外程序员的疑问与解答,希望能对你有所帮助,好了,下面开始学习吧。

AOSP的libc++.so与NDK的libc++_shared.so相同吗? 教程 第1张

问题描述

我在一个Android应用程序中工作,其中一个共享库(我在Android Studio中构建的,我们称之为libA.so)动态加载供应商提供的另一个共享库(我们称之为libB.so)。我知道我不应该在我的应用程序(https://developer.android.com/ndk/guides/cpp-support.html#important_considerations)中使用多个C++运行时库,所以我们决定在两个库中使用c++_Shared。

libB.so(供应商提供的)是在构建AOSP时编译和链接的(供应商坚持以这种方式构建库,无能为力)。libB.so的生成文件正在将STL标志设置为c++_Shared,并如下所示:

LOCAL_NDK_STL_VARIANT := c++_shared

当我查看libB.so库中所需的标记时,我可以看到对libc++.so

的依赖

 0x0000000000000001 (NEEDED) Shared library: [libdl.so]
 0x0000000000000001 (NEEDED) Shared library: [libc++.so] <----
 0x0000000000000001 (NEEDED) Shared library: [libc.so]
 0x0000000000000001 (NEEDED) Shared library: [libm.so]
 0x000000000000000e (SONAME) Library soname: [libB.so]

当我运行readelf -d libc++.so来检查AOSP的libc++的内容时,我得到这个

Dynamic section at offset 0xe4b40 contains 29 entries:
  Tag  Type Name/Value
 0x0000000000000003 (PLTGOT) 0xe6310
 0x0000000000000002 (PLTRELSZ)  22128 (bytes)
 0x0000000000000017 (JMPREL) 0x39ff8
 0x0000000000000014 (PLTREL) RELA
 0x0000000000000007 (RELA)0x2ce58
 0x0000000000000008 (RELASZ) 53664 (bytes)
 0x0000000000000009 (RELAENT)24 (bytes)
 0x000000006ffffff9 (RELACOUNT) 380
 0x0000000000000006 (SYMTAB) 0x238
 0x000000000000000b (SYMENT) 24 (bytes)
 0x0000000000000005 (STRTAB) 0xdeb8
 0x000000000000000a (STRSZ)  102917 (bytes)
 0x000000006ffffef5 (GNU_HASH)  0x270c0
 0x0000000000000001 (NEEDED) Shared library: [libdl.so]
 0x0000000000000001 (NEEDED) Shared library: [libc.so]
 0x0000000000000001 (NEEDED) Shared library: [libm.so]
 0x000000000000000e (SONAME) Library soname: [libc++.so]
 0x000000000000001a (FINI_ARRAY)0xe08e0
 0x000000000000001c (FINI_ARRAYSZ) 8 (bytes)
 0x0000000000000019 (INIT_ARRAY)0xe5b38
 0x000000000000001b (INIT_ARRAYSZ) 8 (bytes)
 0x000000000000001e (FLAGS)  BIND_NOW
 0x000000006ffffffb (FLAGS_1)Flags: NOW
 0x000000006ffffff0 (VERSYM) 0x2bb7c
 0x000000006ffffffc (VERDEF) 0x2cddc
 0x000000006ffffffd (VERDEFNUM) 1
 0x000000006ffffffe (VERNEED)0x2cdf8
 0x000000006fffffff (VERNEEDNUM)2
 0x0000000000000000 (NULL)0x0

我知道NDK也提供了libc++.so,但当我在Android NDK分发的库中运行相同的命令时,我收到错误

readelf: Error: libc++.so: Failed to read file header

如果我没有记错的话,这是因为在NDK中,libc++.so实际上是一个链接器脚本。

libA.so(我用我的应用程序构建并加载libB.so)以对libc++_shared.so

的依赖结束

Dynamic section at offset 0x4bca50 contains 28 entries:
  Tag  Type Name/Value
 0x0000000000000001 (NEEDED) Shared library: [libdl.so]
 0x0000000000000001 (NEEDED) Shared library: [liblog.so]
 0x0000000000000001 (NEEDED) Shared library: [libc++_shared.so] <---
 0x0000000000000001 (NEEDED) Shared library: [libc.so]
 0x000000000000000e (SONAME) Library soname: [libA.so]

我认为我不能(或不应该)在我的应用程序中同时捆绑libc++.solibc++_shared.so

那么,AOSP的libc++.so是否与NDK的libc++_shared.so相同?

有人知道为什么AOSP在使用LOCAL_NDK_STL_VARIANT := c++_shared时也会向libc++.so而不是libc++_shared.so添加动态依赖项?我是否应该要求我的提供商改为链接到libc++_shared.so?也许有人有更好的建议来修复此依赖项不匹配。

推荐答案

不,它们不是等价的。AOSP中的libc++.so是基于最新的(从技术上讲,它是API级别)API级别构建的,没有liband roid_support。它是用一组不同的标志构建的,并且可能是一个不同的ABI。它是用一组体系结构标志构建的,这些标志允许编译器使用并非所有Android设备上都可用的指令。它也是与NDK中的版本不同的版本,但对于不同的NDK版本也是如此,在决定它们是否兼容方面没有那么重要。

如果供应商将libB.so提供给您以包含在您的应用程序中,则他们的构建不正确。正如您已经注意到的,它链接到平台libc++.so,而应用程序无法访问该平台。您这边没有修复程序;供应商需要提供适当的NDK库。如果他们希望继续使用AOSP生成系统,则需要设置LOCAL_SDK_VERSION,以便LOCAL_NDK_STL_VARIANT不会被忽略。

如果供应商提供的设备将此库安装到系统映像中(即/system/lib64/libB.so,不包括在您的应用程序中),则适用@Alex-Cohn答案中的指导。这就是像liband roid.so这样的官方NDK库的构建方式。它们链接到系统的libc++.so,但只向应用程序公开一个C ABI。只要供应商遵循这些指导原则,就可以了。

正如Alex提到的,您引用的文档比实际情况略有限制。可以在同一个程序中使用多个STL(否则NDK应用程序根本不会工作,因为平台和应用程序使用不同的STL),但它确实需要非常仔细地管理ABI的外围应用程序,并非常小心地避免违反ODR。

好了关于AOSP的libc++.so与NDK的libc++_shared.so相同吗?的教程就到这里就结束了,希望趣模板源码网找到的这篇技术文章能帮助到大家,更多技术教程可以在站内搜索。