動(dòng)態(tài)鏈接庫(kù)、靜態(tài)庫(kù)、import庫(kù)區(qū)別
動(dòng)態(tài)鏈接庫(kù)(Dynamic Linked Library):
Windows為應(yīng)用程序提供了豐富的函數(shù)調(diào)用,這些函數(shù)調(diào)用都包含在動(dòng)態(tài)鏈接庫(kù)中。其中有3個(gè)最重要的DLL,Kernel32.dll,它包含用于管理內(nèi)存、進(jìn)程和線程的各個(gè)函數(shù);
User32.dll,它包含用于執(zhí)行用戶界面任務(wù)(如窗口的創(chuàng)建和消息的傳送)的各個(gè)函數(shù);GDI32.dll,它包含用于畫(huà)圖和顯示文本的各個(gè)函數(shù)。
靜態(tài)庫(kù)(Static Library):
函數(shù)和數(shù)據(jù)被編譯進(jìn)一個(gè)二進(jìn)制文件(通常擴(kuò)展名為.LIB)。在使用靜態(tài)庫(kù)的情況下,在編譯鏈接可執(zhí)行文件時(shí),鏈接器從庫(kù)中復(fù)制這些函數(shù)和數(shù)據(jù)并把它們和應(yīng)用程序的其它模塊
組合起來(lái)創(chuàng)建最終的可執(zhí)行文件(.EXE文件)。
導(dǎo)入庫(kù)(Import Library):
在使用動(dòng)態(tài)鏈接庫(kù)的時(shí)候,往往提供兩個(gè)文件:一個(gè)引入庫(kù)和一個(gè)DLL。引入庫(kù)包含被DLL導(dǎo)出的函數(shù)和變量的符號(hào)名,DLL包含實(shí)際的函數(shù)和數(shù)據(jù)。在編譯鏈接可執(zhí)行文件時(shí),只需
要鏈接引入庫(kù),DLL中的函數(shù)代碼和數(shù)據(jù)并不復(fù)制到可執(zhí)行文件中,在運(yùn)行的時(shí)候,再去加載DLL,訪問(wèn)DLL中導(dǎo)出的函數(shù)。
在運(yùn)行Windows程序時(shí),它通過(guò)一個(gè)被稱作“動(dòng)態(tài)鏈接”的進(jìn)程與Windows相接。一個(gè)Windows的.EXE文件擁有它使用不同動(dòng)態(tài)鏈接庫(kù)的引用,所使用的函數(shù)即在那里。當(dāng)Windows程
序被加載到內(nèi)存中時(shí),程序中的調(diào)用被指向DLL函數(shù)的入口,如果DLL不在內(nèi)存中,系統(tǒng)就將其加載到內(nèi)存中。
當(dāng)鏈接Windows程序以產(chǎn)生一個(gè)可執(zhí)行文件時(shí),你必須鏈接由編程環(huán)境提供的專門(mén)的“導(dǎo)入庫(kù)(import library)庫(kù)”。這些導(dǎo)入庫(kù)包含了動(dòng)態(tài)鏈接庫(kù)名稱和所有Windows函數(shù)調(diào)用的
引用信息。鏈接程序使用該信息在.EXE文件中構(gòu)造一個(gè)表,當(dāng)加載程序時(shí),Windows使用它將調(diào)用轉(zhuǎn)換為Windows函數(shù)。
靜態(tài)庫(kù)與導(dǎo)入庫(kù)的區(qū)別:
導(dǎo)入庫(kù)和靜態(tài)庫(kù)的區(qū)別很大,他們實(shí)質(zhì)是不一樣的東西。靜態(tài)庫(kù)本身就包含了實(shí)際執(zhí)行代碼、符號(hào)表等等,而對(duì)于導(dǎo)入庫(kù)而言,其實(shí)際的執(zhí)行代碼位于動(dòng)態(tài)庫(kù)中,導(dǎo)入庫(kù)只包含了
地址符號(hào)表等,確保程序找到對(duì)應(yīng)函數(shù)的一些基本地址信息。
靜態(tài)鏈接與動(dòng)態(tài)鏈接:
靜態(tài)鏈接方法:#pragma comment(lib, "test.lib") ,靜態(tài)鏈接的時(shí)候,載入代碼就會(huì)把程序會(huì)用到的動(dòng)態(tài)代碼或動(dòng)態(tài)代碼的地址確定下來(lái)
靜態(tài)庫(kù)的鏈接可以使用靜態(tài)鏈接,動(dòng)態(tài)鏈接庫(kù)也可以使用這種方法鏈接導(dǎo)入庫(kù)
動(dòng)態(tài)鏈接方法:LoadLibrary()/GetProcessAddress()和FreeLibrary(),使用這種方式的程序并不在一開(kāi)始就完成動(dòng)態(tài)鏈接,而是直到真正調(diào)用動(dòng)態(tài)庫(kù)代碼時(shí),載入程序才計(jì)算(被調(diào)用的那部分)動(dòng)態(tài)代碼的邏輯地址,然后等到某個(gè)時(shí)候,程序又需要調(diào)用另外某塊動(dòng)態(tài)代碼時(shí),載入程序又去計(jì)算這部分代碼的邏輯地址,所以,這種方式使程序初始化時(shí)間較短,但運(yùn)行期間的性能比不上靜態(tài)鏈接的程序。
在軟件開(kāi)發(fā)的過(guò)程中,大家經(jīng)常會(huì)或多或少的使用別人編寫(xiě)的或者系統(tǒng)提供的動(dòng)態(tài)庫(kù)或靜態(tài)庫(kù),但是究竟是使用靜態(tài)庫(kù)還是動(dòng)態(tài)庫(kù)呢?他們的適用條件是什么呢?
簡(jiǎn)單的說(shuō),靜態(tài)庫(kù)和應(yīng)用程序編譯在一起,在任何情況下都能運(yùn)行,而動(dòng)態(tài)庫(kù)是動(dòng)態(tài)鏈接,顧名思義就是在應(yīng)用程序啟動(dòng)的時(shí)候才會(huì)鏈接,所以,當(dāng)用戶的系統(tǒng)上沒(méi)有該動(dòng)態(tài)庫(kù)時(shí),應(yīng)用程序就會(huì)運(yùn)行失敗。再看它們的特點(diǎn):
動(dòng)態(tài)庫(kù):
1.共享:多個(gè)應(yīng)用程序可以使用同一個(gè)動(dòng)態(tài)庫(kù),啟動(dòng)多個(gè)應(yīng)用程序的時(shí)候,只需要將動(dòng)態(tài)庫(kù)加載到內(nèi)存一次即可;
2.開(kāi)發(fā)模塊好:要求設(shè)計(jì)者對(duì)功能劃分的比較好。
靜態(tài)庫(kù):代碼的裝載速度快,執(zhí)行速度也比較快,因?yàn)榫幾g時(shí)它只會(huì)把你需要的那部分鏈接進(jìn)去,應(yīng)用程序相對(duì)比較大。但是如果多個(gè)應(yīng)用程序使用的話,會(huì)被裝載多次,浪費(fèi)內(nèi)存。
總上,我個(gè)人認(rèn)為,如果你的系統(tǒng)上有多個(gè)應(yīng)用程序都使用該庫(kù)的話,就把它編譯成動(dòng)態(tài)庫(kù),這樣雖然剛啟動(dòng)的時(shí)候加載比較慢,但是多任務(wù)的時(shí)候會(huì)比較節(jié)省內(nèi)存;如果你的系統(tǒng)上只有一到兩個(gè)應(yīng)用使用該庫(kù),并且使用的API比較少的話,就編譯成靜態(tài)庫(kù)吧,一般的靜態(tài)庫(kù)還可以進(jìn)行裁剪編譯,這樣應(yīng)用程序可能會(huì)比較大,但是啟動(dòng)的速度會(huì)大大提高。