鴻蒙HarmonyOS應(yīng)用開發(fā)之C/C++標(biāo)準(zhǔn)庫(kù)機(jī)制概述

OpenHarmony NDK提供業(yè)界標(biāo)準(zhǔn)庫(kù) libc標(biāo)準(zhǔn)庫(kù)版述、 C++標(biāo)準(zhǔn)庫(kù) 澎灸,本文用于介紹C/C++標(biāo)準(zhǔn)庫(kù)在OpenHarmony中的機(jī)制炸宵,開發(fā)者了解這些機(jī)制有助于在NDK開發(fā)過(guò)程中避免相關(guān)問(wèn)題瓜客。

1. C++兼容性

在OpenHarmony系統(tǒng)中俭正,系統(tǒng)庫(kù)與應(yīng)用Native庫(kù)都在使用C++標(biāo)準(zhǔn)庫(kù)(參考 libc++版本 )奸鬓,系統(tǒng)庫(kù)依賴的C++標(biāo)準(zhǔn)庫(kù)隨鏡像版本升級(jí),而應(yīng)用Native庫(kù)依賴的C++標(biāo)準(zhǔn)庫(kù)隨編譯使用的SDK版本升級(jí)掸读,兩部分依賴的C++基礎(chǔ)庫(kù)會(huì)跨多個(gè)大版本串远,產(chǎn)生ABI兼容性問(wèn)題。為了解決此問(wèn)題儿惫,OpenHarmony上把兩部分依賴的C++標(biāo)準(zhǔn)庫(kù)進(jìn)行了區(qū)分澡罚。

  • 系統(tǒng)庫(kù):使用libc++.so, 隨系統(tǒng)鏡像發(fā)布肾请。
  • 應(yīng)用Native庫(kù):使用libc++_shared.so留搔,隨應(yīng)用發(fā)布。

兩個(gè)庫(kù)使用的C++命名空間不一樣铛铁,libc++.so使用__h作為C++符號(hào)的命名空間隔显,libc++_shared.so使用__n1作為C++符號(hào)的命名空間。

注意:系統(tǒng)和應(yīng)用使用的C++標(biāo)準(zhǔn)庫(kù)不能進(jìn)行混用避归,Native API接口當(dāng)前只能是C接口荣月,可以通過(guò)這個(gè)接口隔離兩邊的C++運(yùn)行環(huán)境。因此在使用共享庫(kù)HAR包構(gòu)建應(yīng)用時(shí)梳毙,如果HAR包含的libc++_shared.so不同于應(yīng)用使用的libc++_shared.so版本哺窄,那么只有其中一個(gè)版本會(huì)安裝到應(yīng)用里,可能會(huì)導(dǎo)致不兼容問(wèn)題,可以使用相同的SDK版本更新HAR包解決此問(wèn)題萌业。

已知C++兼容性問(wèn)題:應(yīng)用啟動(dòng)或者dlopen時(shí)hilog報(bào)錯(cuò)symbol not found, s=__emutls_get_address坷襟,原因是OpenHarmony 3.2及之前版本SDK中的libc++_shared.so無(wú)此符號(hào),而OpenHarmony4.0之后版本SDK的libc++_shared.so是有此符號(hào)的生年。解決此問(wèn)題需要更新應(yīng)用或者共享庫(kù)HAR包的SDK版本婴程。

2. musl libc動(dòng)態(tài)鏈接器

2.1 動(dòng)態(tài)庫(kù)加載命名空間隔離

動(dòng)態(tài)庫(kù)加載命名空間(namespace,下面統(tǒng)稱為ns)是動(dòng)態(tài)鏈接器設(shè)計(jì)的一個(gè)概念(區(qū)別于C++語(yǔ)言中的命名空間)抱婉,其設(shè)計(jì)的主要目的是為了在進(jìn)程中做native庫(kù)資源訪問(wèn)的管控档叔,以達(dá)到安全隔離的目的。例如系統(tǒng)native庫(kù)允許加載系統(tǒng)目錄(/system/lib64;/vendor/lib64等)下的native庫(kù)蒸绩,但是普通應(yīng)用native庫(kù)僅允許加載普通應(yīng)用native庫(kù)和ndk庫(kù)衙四,而不允許直接加載系統(tǒng)native庫(kù)。

動(dòng)態(tài)鏈接器無(wú)論是在加載編譯依賴(DT_NEEDED)中指定的共享庫(kù)患亿,還是調(diào)用dlopen加載指定的共享庫(kù)传蹈,都需要關(guān)聯(lián)到具體的ns。

OpenHarmony中動(dòng)態(tài)庫(kù)加載namespace配置的情況

  • default ns:動(dòng)態(tài)鏈接器啟動(dòng)時(shí)默認(rèn)創(chuàng)建的ns步藕,它可以搜索/system/lib{abi};/vendor/lib{abi}等系統(tǒng)目錄路徑下的so惦界。
  • ndk ns:動(dòng)態(tài)鏈接器啟動(dòng)時(shí)默認(rèn)創(chuàng)建的ns,它可以搜索/system/lib{abi}/ndk目錄下的so咙冗,主要是暴露了NDK接口的so沾歪。
  • app ns: 應(yīng)用啟動(dòng)時(shí)創(chuàng)建的ns,它的搜索路徑一般是應(yīng)用的安裝路徑(可能為沙箱路徑)乞娄,即可加載應(yīng)用的so瞬逊。

當(dāng)前這一套命名空間機(jī)制主要限制了應(yīng)用native庫(kù)和系統(tǒng)native庫(kù)之間的調(diào)用,如圖所示仪或,具體規(guī)則為

  1. default ns和ndk ns可以互相訪問(wèn)全部so确镊,不能訪問(wèn)app ns的so。
  2. app ns能訪問(wèn)ndk ns的全部so范删,不能訪問(wèn)default ns的so蕾域。

2.2 rpath機(jī)制

rpath(run-time path)是在運(yùn)行時(shí)指定共享庫(kù)搜索路徑的機(jī)制。該機(jī)制允許在可執(zhí)行文件或共享庫(kù)中嵌入一個(gè)用于在運(yùn)行時(shí)指定庫(kù)的搜索路徑的信息到旦。

由于上文介紹的命名空間隔離機(jī)制旨巷,應(yīng)用僅允許加載對(duì)應(yīng)安裝目錄拼接native庫(kù)路徑下(例如arm64平臺(tái)上為libs/arm64)的應(yīng)用native庫(kù),當(dāng)應(yīng)用程序涉及加載較多的native庫(kù)添忘,期望創(chuàng)建多個(gè)native庫(kù)加載路徑方便管理采呐,但是會(huì)導(dǎo)致無(wú)法加載新創(chuàng)建目錄下的native庫(kù),這種情況可以通過(guò)rpath機(jī)制編譯時(shí)指定搜索路徑搁骑。

例如斧吐,應(yīng)用安裝目錄lib/arm64下的libhello.so依賴新創(chuàng)建路徑lib/arm64/module下的libworld.so又固,那么在應(yīng)用的CMakeList.txt里設(shè)置上rpath編譯選項(xiàng)后編譯,使用readelf查看libhello.so的rpath配置如圖所示煤率,$ORIGIN為libhello.so所在路徑仰冠,運(yùn)行時(shí)即可正常加載module目錄下的libworld.so。

SET(CMAKE_BUILD_WITH_INSTALL_RPATH TRUE)
SET(CMAKE_INSTALL_RPATH "\${ORIGIN}/module")

2.3 支持dlclose

支持使用dlclose真實(shí)卸載動(dòng)態(tài)庫(kù)的能力蝶糯。

2.4 支持symbol-version機(jī)制

symbol-version是libc在動(dòng)態(tài)鏈接-符號(hào)重定位階段的符號(hào)檢索機(jī)制洋只,支持不同版本的符號(hào)重定位,也可以幫助解決重復(fù)符號(hào)的問(wèn)題昼捍∈缎椋可參考 LD Version Scripts (GNU Gnulib)

寫在最后

  • 如果你覺得這篇內(nèi)容對(duì)你還蠻有幫助,我想邀請(qǐng)你幫我三個(gè)小忙:
  • 點(diǎn)贊妒茬,轉(zhuǎn)發(fā)舷礼,有你們的 『點(diǎn)贊和評(píng)論』,才是我創(chuàng)造的動(dòng)力郊闯。
  • 關(guān)注小編,同時(shí)可以期待后續(xù)文章ing??蛛株,不定期分享原創(chuàng)知識(shí)团赁。
  • 想要獲取更多完整鴻蒙最新學(xué)習(xí)知識(shí)點(diǎn),請(qǐng)移步前往小編:https://gitee.com/MNxiaona/733GH/blob/master/jianshu
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末谨履,一起剝皮案震驚了整個(gè)濱河市欢摄,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌笋粟,老刑警劉巖怀挠,帶你破解...
    沈念sama閱讀 219,490評(píng)論 6 508
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場(chǎng)離奇詭異害捕,居然都是意外死亡绿淋,警方通過(guò)查閱死者的電腦和手機(jī),發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 93,581評(píng)論 3 395
  • 文/潘曉璐 我一進(jìn)店門尝盼,熙熙樓的掌柜王于貴愁眉苦臉地迎上來(lái)吞滞,“玉大人,你說(shuō)我怎么就攤上這事盾沫〔迷” “怎么了?”我有些...
    開封第一講書人閱讀 165,830評(píng)論 0 356
  • 文/不壞的土叔 我叫張陵赴精,是天一觀的道長(zhǎng)佩捞。 經(jīng)常有香客問(wèn)我,道長(zhǎng)蕾哟,這世上最難降的妖魔是什么一忱? 我笑而不...
    開封第一講書人閱讀 58,957評(píng)論 1 295
  • 正文 為了忘掉前任莲蜘,我火速辦了婚禮,結(jié)果婚禮上掀潮,老公的妹妹穿的比我還像新娘菇夸。我一直安慰自己,他們只是感情好仪吧,可當(dāng)我...
    茶點(diǎn)故事閱讀 67,974評(píng)論 6 393
  • 文/花漫 我一把揭開白布庄新。 她就那樣靜靜地躺著,像睡著了一般薯鼠。 火紅的嫁衣襯著肌膚如雪择诈。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 51,754評(píng)論 1 307
  • 那天出皇,我揣著相機(jī)與錄音羞芍,去河邊找鬼。 笑死郊艘,一個(gè)胖子當(dāng)著我的面吹牛荷科,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播纱注,決...
    沈念sama閱讀 40,464評(píng)論 3 420
  • 文/蒼蘭香墨 我猛地睜開眼畏浆,長(zhǎng)吁一口氣:“原來(lái)是場(chǎng)噩夢(mèng)啊……” “哼!你這毒婦竟也來(lái)了狞贱?” 一聲冷哼從身側(cè)響起刻获,我...
    開封第一講書人閱讀 39,357評(píng)論 0 276
  • 序言:老撾萬(wàn)榮一對(duì)情侶失蹤,失蹤者是張志新(化名)和其女友劉穎瞎嬉,沒想到半個(gè)月后蝎毡,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 45,847評(píng)論 1 317
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡氧枣,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 37,995評(píng)論 3 338
  • 正文 我和宋清朗相戀三年沐兵,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片便监。...
    茶點(diǎn)故事閱讀 40,137評(píng)論 1 351
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡痒筒,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出茬贵,到底是詐尸還是另有隱情簿透,我是刑警寧澤,帶...
    沈念sama閱讀 35,819評(píng)論 5 346
  • 正文 年R本政府宣布解藻,位于F島的核電站老充,受9級(jí)特大地震影響,放射性物質(zhì)發(fā)生泄漏螟左。R本人自食惡果不足惜啡浊,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,482評(píng)論 3 331
  • 文/蒙蒙 一觅够、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧巷嚣,春花似錦喘先、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 32,023評(píng)論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽(yáng)。三九已至坝茎,卻和暖如春涤姊,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背嗤放。 一陣腳步聲響...
    開封第一講書人閱讀 33,149評(píng)論 1 272
  • 我被黑心中介騙來(lái)泰國(guó)打工思喊, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留,地道東北人次酌。 一個(gè)月前我還...
    沈念sama閱讀 48,409評(píng)論 3 373
  • 正文 我出身青樓恨课,卻偏偏與公主長(zhǎng)得像,于是被迫代替她去往敵國(guó)和親岳服。 傳聞我的和親對(duì)象是個(gè)殘疾皇子庄呈,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 45,086評(píng)論 2 355

推薦閱讀更多精彩內(nèi)容