簡體   English   中英

是AOSP的libc ++。所以和NDK的libc ++ _ shared.so一樣嗎?

[英]Is AOSP's libc++.so the same as NDK's libc++_shared.so?

我正在一個Android應用程序中工作,其中一個共享庫(我在Android Studio中構建,我們稱之為libA.so )由供應商動態加載另一個共享庫提供程序(讓我們稱之為libB.so )。 我知道我不應該在我的應用程序中使用多個C ++運行時庫( https://developer.android.com/ndk/guides/cpp-support.html#important_considerations ),所以我們決定使用c ++ _ shared in兩個庫。

構建AOSP時, libB.so (由供應商提供的)編譯和鏈接(供應商堅持以這種方式構建庫,對此無能為力)。 libB.so的makefile是將STL標志設置為c ++ _ shared:

LOCAL_NDK_STL_VARIANT := c++_shared

當我查看libB.so庫中的NEEDED標記時,我可以看到對libc++.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會為libc++.so添加動態依賴libc++.so即使使用了LOCAL_NDK_STL_VARIANT := c++_shared也不是libc++_shared.so 我應該要求我的提供商鏈接libc++_shared.so嗎? 也許有人有更好的建議來解決這種依賴性不匹配問題。

不,他們不等同。 libc ++。所以在AOSP中是針對最新的(技術上是未來的 API級別)API級別而沒有libandroid_support構建的。 它使用不同的標志集構建,並且可能是不同的ABI。 它使用一組體系結構標志構建,允許編譯器使用所有Android設備上不可用的指令。 它也與NDK中的版本不同,但對於不同的NDK版本也是如此,在決定它們是否兼容時不太重要。

如果供應商向您提供libB.so以包含在您的應用程序中,則他們正在錯誤地構建它。 正如您所注意到的,它是與平台libc ++的鏈接。因此,應用程序無法訪問它。 你身邊沒有任何解決辦法; 供應商需要提供適當的NDK庫。 如果他們想繼續使用AOSP構建系統,則需要設置LOCAL_SDK_VERSION以便不忽略LOCAL_NDK_STL_VARIANT

如果供應商提供的設備已將此庫安裝到系統映像(即/system/lib64/libB.so, 包含在您的應用程序中),那么@ alex-cohn的答案中的指導適用。 這就是建立像libandroid.so這樣的官方NDK庫的方式。 它們鏈接到系統的libc ++。所以,但只向應用程序公開C ABI。 只要供應商遵循這些准則,這很好。

正如亞歷克斯所提到的那樣,你所引用的文件比現實情況稍微有些限制。 可能在同一個程序中使用多個補充交易(否則NDK應用程序不會在所有的工作,因為平台和應用程序使用不同的補充交易),但它確實需要您的ABI的表面積和良好的非常細致的管理謹慎行事,以避免違反ODR。

首先,可以在一個應用程序中混合使用不同的C ++運行時,只要它們不進行交互即可 這意味着,C ++對象(包括異常)不應跨越其共享庫的邊界。 因此,如果您的libB.so提供了一個extern“C”公共API,您可以安全地使用為任何 C ++運行時編譯的組件中的這些函數,甚至是stlport_static

如果供應商lib不導出純C API,則違反了體系結構規定(請參閱https://source.android.com/devices/architecture/images/vndk_design_android_o.pdf ,第27頁)。 在這種情況下,您可能還需要構建依賴的libA.so作為AOSP的一部分。 如果您選擇將庫更緊密地耦合到libB.so ,例如擴展其某些類,在libA / libB邊界上拋出異常等,則可以這樣做。

請注意,從Android N開始,系統鏈接器會保護平台庫(/ system / lib和/ vendor / lib中的平台庫)不被用戶代碼刪除 您應該考慮將libBlibA或兩者添加到白名單中

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM