Linux下動(dòng)態(tài)庫(kù)的顯性調(diào)用(dlopen)和隱性調(diào)用區(qū)別
在linux環(huán)境下編程,我們?nèi)绻胍褂玫谌降膸?kù),基本上有以下幾種方式。
1、將第三方庫(kù)的源碼合并到我們的工程項(xiàng)目代碼中,一起編譯。
2、將第三方庫(kù)編譯成靜態(tài)庫(kù)(xxx.a),我們?cè)谑褂脮r(shí),在Makefile中引用該靜態(tài)庫(kù)。
3、將第三方庫(kù)編譯成動(dòng)態(tài)庫(kù)(xxx.so), 我們?cè)谑褂脮r(shí),隱性調(diào)用該動(dòng)態(tài)庫(kù),具體表現(xiàn)為需要 在程序中包含動(dòng)態(tài)庫(kù)的 頭文件,同時(shí)需要在/usr/lib路徑下,存放動(dòng)態(tài)庫(kù)文件,以便程序調(diào)用。
4、將第三方庫(kù)編譯成動(dòng)態(tài)庫(kù)(xxx.so), 我們?cè)谑褂脮r(shí),顯性調(diào)用該動(dòng)態(tài)庫(kù),在程序中,不需要包含動(dòng)態(tài)庫(kù)的頭文件,使用 dlopen、dlsym等接口函數(shù)調(diào)用該動(dòng)態(tài)庫(kù)。
在上述四種方式中:
第 1 和 2 種,本質(zhì)上是一樣的,使用靜態(tài)庫(kù),編譯時(shí),會(huì)將靜態(tài)庫(kù)的內(nèi)容合并到工程代碼中,唯一區(qū)別的是當(dāng)我們拿不到第三方庫(kù)的源碼時(shí),可以直接使用靜態(tài)庫(kù),相當(dāng)于使用一個(gè)黑盒子,靜態(tài)庫(kù)提供接口。
第 3 和 4 種方式,我們常用的是第3種方式,也就是隱性調(diào)用,但是顯性調(diào)用一種程序插件的概念,隨用隨加載,不用不加載。
顯性調(diào)用和隱性調(diào)用區(qū)別
名稱(chēng)使用方式動(dòng)態(tài)庫(kù)文件內(nèi)存其他隱性調(diào)用引用動(dòng)態(tài)庫(kù)頭文件需要提前拷貝到/usr/lib/目錄,否則程序無(wú)法執(zhí)行程序開(kāi)始執(zhí)行,不管是否用到動(dòng)態(tài)庫(kù)功能,都會(huì)將動(dòng)態(tài)庫(kù)讀到內(nèi)存中不會(huì)額外調(diào)用插件庫(kù)顯性調(diào)用不需要引用動(dòng)態(tài)庫(kù)頭文件,但是需要引用不一定,如果程序不會(huì)執(zhí)行到動(dòng)態(tài)庫(kù)功能,則不需要拷貝,即便使用,也可以使用絕對(duì)路徑來(lái)使用,不需要拷貝到/usr/lib/目錄下只有程序執(zhí)行到dlopen時(shí),才會(huì)將動(dòng)態(tài)庫(kù)讀入內(nèi)存會(huì)額外調(diào)用linux插件庫(kù),來(lái)支持顯性調(diào)用。
在使用dlopen時(shí),編譯時(shí)候要加入 -ldl (指定dl庫(kù)),若dl庫(kù)有問(wèn)題,那么在運(yùn)行時(shí)調(diào)用dlopen時(shí)會(huì)出現(xiàn)段錯(cuò)誤。因此要保證dl庫(kù)沒(méi)問(wèn)題。
開(kāi)發(fā)時(shí)遇到一個(gè)問(wèn)題,本地需要編寫(xiě)一個(gè)so庫(kù)給應(yīng)用程序提供接口,在應(yīng)用程序中使用dlopen來(lái)打開(kāi)so庫(kù),但是運(yùn)行時(shí)調(diào)用dlopen時(shí)出現(xiàn)段錯(cuò)誤。
原因是應(yīng)用程序編譯時(shí)引用應(yīng)用程序中l(wèi)ib下的dl庫(kù),該庫(kù)有問(wèn)題導(dǎo)致運(yùn)行時(shí)出現(xiàn)段錯(cuò)誤。解決方式就是把應(yīng)用程序中l(wèi)ib下的dl庫(kù)給替換掉。
小結(jié)
顯性調(diào)用更多的是體現(xiàn)在“插件”的思想,使用起來(lái)更加靈活,比如大的工程項(xiàng)目中,同樣一套代碼,提供不一樣的功能時(shí),為了節(jié)省內(nèi)存、磁盤(pán)容量,可以按需加載。在使用方式上,顯性調(diào)用相比隱性調(diào)用,略復(fù)雜,需要增加額外的轉(zhuǎn)換代碼,而隱性調(diào)用,只需要包含動(dòng)態(tài)庫(kù)頭文件,在代碼中,直接調(diào)用API即可。在生產(chǎn)程序中,如果對(duì)內(nèi)存或磁盤(pán)、啟動(dòng)速度沒(méi)有嚴(yán)苛的要求,盡量使用隱形調(diào)用,方便程序編寫(xiě)和維護(hù)。