鄒本娜
[摘要]動(dòng)態(tài)鏈接庫(kù)技術(shù)是實(shí)現(xiàn)和設(shè)計(jì)程序常用的技術(shù)。分析和比較Windows和Linax兩種操作系統(tǒng)動(dòng)態(tài)技術(shù),為對(duì)動(dòng)態(tài)鏈接庫(kù)技術(shù)的學(xué)習(xí)提供有益的借鑒。
[關(guān)鍵詞]動(dòng)態(tài)鏈接庫(kù)共享對(duì)象技術(shù)程序移植
中圖分類號(hào):TP3文獻(xiàn)標(biāo)識(shí)碼:A文章編號(hào):1 671—7597(2009)1010092—01
一、引言
動(dòng)態(tài)鏈(Dynamic Link Library abbr,DLL)技術(shù)是程序設(shè)計(jì)中經(jīng)常采用的技術(shù),其目的是縮減程序,節(jié)省空間,提高效率。采用動(dòng)態(tài)庫(kù)技術(shù)具有很高的靈活性,對(duì)于升級(jí)軟件版本更加容易,可以帶來(lái)如運(yùn)行時(shí)占用較少的硬件資源,有助于模塊式化體系結(jié)構(gòu)開(kāi)發(fā),修改升級(jí)軟件方便,隱藏實(shí)現(xiàn)細(xì)節(jié)等方便。
在Windows和Linux操作系統(tǒng)中,都可以采用這種方式進(jìn)行軟件設(shè)計(jì),但它們的調(diào)用方式以及編程方式不盡相同。本文將在介紹分析Windows系統(tǒng)及Linux系統(tǒng)下的動(dòng)態(tài)鏈接技術(shù)的基礎(chǔ)上對(duì)兩種操作系統(tǒng)的處理方式進(jìn)行了簡(jiǎn)要的比較。
二、Windows動(dòng)態(tài)庫(kù)技術(shù)
Windows本身就有三個(gè)基本的動(dòng)態(tài)鏈接庫(kù),是windows的主要組成部分,它們分別是KERNEL(負(fù)責(zé)內(nèi)存管理、任務(wù)調(diào)度),USER(管理用戶界面),GDI(圖形設(shè)備接口)。另外,Windows系統(tǒng)中以FUN、DRV或DLL為擴(kuò)展名的文件都是動(dòng)態(tài)鏈按庫(kù)的例子。
Windows的動(dòng)態(tài)鏈接機(jī)制是動(dòng)態(tài)鏈接庫(kù)的上述優(yōu)勢(shì)得以實(shí)現(xiàn)的基礎(chǔ)。一旦windows應(yīng)用程序調(diào)用了DLL中的函數(shù),那么在生成相應(yīng)的Windows可執(zhí)行文件時(shí),所調(diào)用的函數(shù)的代碼并沒(méi)有被鏈接程序拷貝到應(yīng)用程序的可執(zhí)行文件中去,而是僅僅在其中加入了所調(diào)用函數(shù)的描述信息。僅當(dāng)應(yīng)用程序被裝入內(nèi)存開(kāi)始運(yùn)行時(shí),在Windows的管理下,才在應(yīng)用程序和相應(yīng)的DLL之間建立連接關(guān)系。當(dāng)要執(zhí)行所調(diào)用的DLL中的函數(shù)時(shí),根據(jù)鏈接時(shí)產(chǎn)生的重定位信息,Windows轉(zhuǎn)去執(zhí)行DLL中相應(yīng)的函數(shù)代碼。這樣就不難理解,DLL具有自己的代碼段和數(shù)據(jù)段。一個(gè)DLL在內(nèi)存中只有一個(gè)實(shí)例,多個(gè)應(yīng)用程序使用同一個(gè)DLL時(shí),將共享內(nèi)存中的一個(gè)實(shí)例。另外,在Windows管理下,動(dòng)態(tài)鏈接庫(kù)的實(shí)例擁有并維護(hù)自己的一個(gè)引用計(jì)數(shù),這個(gè)引用計(jì)數(shù)表明當(dāng)前和該庫(kù)進(jìn)行動(dòng)態(tài)鏈接的任務(wù)的個(gè)數(shù)。當(dāng)需要裝入一個(gè)DLL,而內(nèi)存中已經(jīng)存在時(shí),則僅使引用計(jì)數(shù)加1,而且保證使應(yīng)用程序中對(duì)同一個(gè)DLL函數(shù)的調(diào)用都是內(nèi)存中的相同的副本。當(dāng)一個(gè)應(yīng)用程序結(jié)束時(shí),相應(yīng)的DLL引用計(jì)數(shù)減1。僅當(dāng)引用計(jì)數(shù)值為0時(shí),Windows這才把相應(yīng)的DLL卸出內(nèi)存。可見(jiàn)DLL能夠經(jīng)濟(jì)高效地使用內(nèi)存。
三、Unux共事對(duì)象技術(shù)
在Linux操作系統(tǒng)中,采用了很多共享對(duì)象技術(shù)(Shared Object),雖然它和windows里的動(dòng)態(tài)庫(kù)相對(duì)應(yīng),但它并不稱為動(dòng)態(tài)庫(kù)。相應(yīng)的共享對(duì)象文件以,so作為后級(jí),為了方便,在本文中,對(duì)該概念不進(jìn)行專門區(qū)分。Linux系統(tǒng)的/lib以及標(biāo)準(zhǔn)圖形界面的/usr/XllR6/lib等目錄里面,就有許多以so結(jié)尾的共享對(duì)象。同樣,在Linux下也有靜態(tài)函數(shù)庫(kù)這種調(diào)用方式,相應(yīng)的后綴以,結(jié)束。Linux采用該共享對(duì)象技術(shù)以方便程序間共享,節(jié)省程序占有空間,增加程序的可擴(kuò)展性和靈活性。Linux還可以通過(guò)LDPRELOAD變量讓開(kāi)發(fā)人員可以使用自己的程序庫(kù)中的模塊來(lái)替換系統(tǒng)模塊。
同Windows系統(tǒng)一樣,在Linux中創(chuàng)建和使用動(dòng)態(tài)庫(kù)是比較容易的事情,在編譯函數(shù)庫(kù)源程序時(shí)加上shared選取即可,這樣所生成的執(zhí)行程序就是動(dòng)態(tài)鏈接庫(kù)。通常這樣的程序以so為后綴,在Linux動(dòng)態(tài)庫(kù)程序設(shè)計(jì)過(guò)程中,通常流程是編寫用戶的接口文件,通常是,h文件,編寫實(shí)際的函數(shù)文件,以,c或,opp為后綴,再編寫makefile文件。對(duì)于較小的動(dòng)態(tài)庫(kù)程序則不必如此,但這樣設(shè)計(jì)會(huì)使程序更加合理。
編譯生成動(dòng)態(tài)鏈接庫(kù)后,進(jìn)而可以在程序中進(jìn)行調(diào)用。在Linux中,可以采用多種調(diào)用方式同Windows的系統(tǒng)目錄(..\system32等)一樣可以將動(dòng)態(tài)庫(kù)文件拷貝到/lib目錄或者在/1ib目錄里面建立符號(hào)連接,以便所有用戶使用。
四、兩種系統(tǒng)動(dòng)態(tài)庫(kù)比較分析
Windows和Linux采用動(dòng)態(tài)鏈接庫(kù)技術(shù)的目的是基本一致的,但由于操作系統(tǒng)不同,他們之間也還是有許多不同之處,主要體現(xiàn)在以下幾個(gè)方面:
1,動(dòng)態(tài)庫(kù)程序編寫。在windows系統(tǒng)下的執(zhí)行文件格式是PE格式,動(dòng)態(tài)庫(kù)需要一個(gè)DllMain函數(shù)作為初始化的入口。通常在導(dǎo)出函數(shù)的聲明時(shí)需要有declspec(dllexport)關(guān)鍵字Linux下的gco編譯的執(zhí)行文件默認(rèn)是ELF格式,不需要初始化入口,亦不需要在函數(shù)中做特別的聲明,編寫比較方便。
2,動(dòng)態(tài)庫(kù)編譯。在Windows系統(tǒng)下面,有方便的調(diào)試編譯環(huán)境,通常不用自己去編寫makefile文件,但在linux target=Linux下面需要自己動(dòng)手編寫makefile文件,因此,必須掌握一定的makefile編寫技巧,通常Linux編譯規(guī)則相對(duì)嚴(yán)格些。
3,動(dòng)態(tài)庫(kù)調(diào)用方面。Windows和Linux對(duì)其下編制的動(dòng)態(tài)庫(kù)都可以采用顯式調(diào)用或隱式調(diào)用,但具體的調(diào)用方式不盡相同。
4,動(dòng)態(tài)庫(kù)輸出函數(shù)查看。在windows中,有許多工具和軟件可用來(lái)查看DLL中輸出的函數(shù)例如命令行方式dumpbin以及vc++工具中的DEPENDS程序。在Linux系統(tǒng)中通常采用n來(lái)查看輸出函數(shù),也可以使用ldd查看程序隱式鏈接的共享對(duì)象文件。
5,對(duì)操作系統(tǒng)的依賴。這兩種動(dòng)態(tài)庫(kù)運(yùn)行依賴于各自的操作系統(tǒng),不能跨平臺(tái)使用。因此,對(duì)于實(shí)現(xiàn)相同功能的動(dòng)態(tài)庫(kù),必須為兩種不同的操作系統(tǒng)提供不同的動(dòng)態(tài)庫(kù)版本。
五、總結(jié)
本文系統(tǒng)分析了Windows和Linux動(dòng)態(tài)庫(kù)實(shí)現(xiàn),從程序編寫、編譯、調(diào)用以及對(duì)操作系統(tǒng)依賴等方面綜合分析和比較了這兩種調(diào)用方式的不同之處,為初學(xué)者對(duì)這兩種動(dòng)態(tài)鏈接技術(shù)的學(xué)習(xí)提供了有益的參考。