日本免费全黄少妇一区二区三区-高清无码一区二区三区四区-欧美中文字幕日韩在线观看-国产福利诱惑在线网站-国产中文字幕一区在线-亚洲欧美精品日韩一区-久久国产精品国产精品国产-国产精久久久久久一区二区三区-欧美亚洲国产精品久久久久

Ubuntu Linux---GNU libc庫(kù)( 三 )


3.5 動(dòng)態(tài)鏈接器(運(yùn)行時(shí)鏈接器)
Linux動(dòng)態(tài)鏈接器(/lib/ld.so.1或/lib64/ld64.so.1)查找和裝載應(yīng)用程序所需的共享庫(kù),準(zhǔn)備應(yīng)用程序的運(yùn)行,然后運(yùn)行應(yīng)用程序 。除非編譯時(shí)為ld指明-static選項(xiàng),否則Linux二進(jìn)制程序都是動(dòng)態(tài)鏈接的 。
【Ubuntu Linux---GNU libc庫(kù)】在所有現(xiàn)代UNIX操作系統(tǒng)上,都有一些環(huán)境變量可以影響動(dòng)態(tài)鏈接器的運(yùn)行 。例如AIX上的環(huán)境變量LIBPATH可以改變動(dòng)態(tài)鏈接器的搜索路徑 。以下環(huán)境變量可以影響到Linux上動(dòng)態(tài)鏈接器的運(yùn)行:
- LD_LIBRARY_PATH,以冒號(hào)分開(kāi)的目錄列表,運(yùn)行時(shí)會(huì)在這些目錄中查找需要的庫(kù) 。
- LD_PRELOAD,以空格分開(kāi)的庫(kù)列表,這些庫(kù)會(huì)在其他所有庫(kù)之前裝載 。這常常用來(lái)有選擇的覆蓋某些共享庫(kù)中的函數(shù) 。
- LD_BIND_NOW,如果該環(huán)境變量設(shè)置成非空字符串,動(dòng)態(tài)鏈接器會(huì)在程序啟動(dòng)時(shí)解析所有符號(hào),而不是首次引用時(shí)才解析符號(hào)(也就是常說(shuō)的“延遲綁定) 。這在使用調(diào)試器時(shí)非常有用 。
- LD_TRACE_LOADED_OBJECTS,如果該環(huán)境變量設(shè)置成非空字符串,程序會(huì)列出它所依賴的共享庫(kù),就像運(yùn)行l(wèi)dd命令一樣,而不是正常的執(zhí)行 。
Linux動(dòng)態(tài)鏈接器采用廣度優(yōu)先(breadth first)的方式解決庫(kù)的依賴關(guān)系 。也就是說(shuō),首先是可執(zhí)行程序所依賴的庫(kù)按照動(dòng)態(tài)節(jié)(dynamic section)列出的順序被裝載進(jìn)來(lái),然后是“第一個(gè)被依賴的庫(kù)所依賴的庫(kù)按照同樣的方法裝載進(jìn)來(lái),以此類(lèi)推,直到所有的依賴關(guān)系都被解決 。
在命令行運(yùn)行下面的命令,會(huì)得到更多關(guān)于Linux動(dòng)態(tài)鏈接器的信息:
(代碼)(P69第最后一行)
$ info ld.so
上一頁(yè);;[1];[2];[3][4];[5];下一頁(yè)
3.5.1 編程接口
Linux提供了一套API來(lái)動(dòng)態(tài)裝載庫(kù) 。下面列出了這些API:
- dlopen,打開(kāi)一個(gè)庫(kù),并為使用該庫(kù)做些準(zhǔn)備 。
- dlsym,在打開(kāi)的庫(kù)中查找符號(hào)的值 。
- dlclose,關(guān)閉庫(kù) 。
- dlerror,返回一個(gè)描述最后一次調(diào)用dlopen、dlsym,或dlclose的錯(cuò)誤信息的字符串 。
C語(yǔ)言用戶需要包含頭文件dlfcn.h才能使用上述API 。glibc還增加了兩個(gè)POSIX標(biāo)準(zhǔn)中沒(méi)有的API:
- dladdr,從函數(shù)指針解析符號(hào)名稱和所在的文件 。
- dlvsym,與dlsym類(lèi)似,只是多了一個(gè)版本字符串參數(shù) 。
在Linux上,使用動(dòng)態(tài)鏈接的應(yīng)用程序需要和庫(kù)libdl.so一起鏈接,也就是使用選項(xiàng)-ldl 。但是,編譯時(shí)不需要和動(dòng)態(tài)裝載的庫(kù)一起鏈接 。程序3-1是一個(gè)在Linux上使用dl*例程的簡(jiǎn)單示例 。
(代碼)(P70-73)
編譯該程序:
(代碼)(P73第5行)
$ make
運(yùn)行程序:
(代碼)(P73第15行)
$ ./main
用ldd命令檢查可執(zhí)行程序:
$ ldd ./main
(代碼)(P73第19行)
可以看到,可執(zhí)行程序main沒(méi)有引用動(dòng)態(tài)裝載的庫(kù) 。
3.5.2 延遲重定位(Lazy Relocation)
延遲重定位/裝載是一個(gè)允許符號(hào)只在需要時(shí)才重定位的特性 。這常在各UNIX系統(tǒng)上解析函數(shù)調(diào)用時(shí)用到 。當(dāng)一個(gè)和共享庫(kù)一起鏈接的應(yīng)用程序幾乎不會(huì)用到該共享庫(kù)中的函數(shù)時(shí),該特性被證明是非常有用的 。這種情況下,只有庫(kù)中的函數(shù)被應(yīng)用程序調(diào)用時(shí),共享庫(kù)才會(huì)被裝載,否則不會(huì)裝載,因此會(huì)節(jié)約一些系統(tǒng)資源 。但是如果把環(huán)境變量LD_BIND_NOW設(shè)置成一個(gè)非空值,所有的重定位操作都會(huì)在程序啟動(dòng)時(shí)進(jìn)行 。也可以在鏈接器命令行通過(guò)使用-z now鏈接器選項(xiàng)使延遲綁定對(duì)某個(gè)特定的共享庫(kù)失效 。需要注意的是,除非重新鏈接該共享庫(kù),否則對(duì)該共享庫(kù)的這種設(shè)置會(huì)一直有效 。
3.5.3 初始化(initializing)和終止化(finalizing)函數(shù)
有時(shí)候,以前的代碼可能用到了兩個(gè)特殊的函數(shù):_init和_fini 。_init和_fini函數(shù)用在裝載和卸載某個(gè)模塊(注釋14)時(shí)分別控制該模塊的構(gòu)造器和析構(gòu)器(或構(gòu)造函數(shù)和析構(gòu)函數(shù)) 。他們的C語(yǔ)言原型如下:

推薦閱讀