問(wèn)題:
一直沒(méi)搞清楚編譯dll后生成的lib
文件到底是干什么用的?如果采用靜態(tài)連接,為什么老是需要lib文件?而通過(guò)loadlibrary則不需要?如果是靜態(tài)連接,是否我的dll
程序一旦改動(dòng)而從新編譯過(guò)后,就還需要從新編譯調(diào)用dll的程序?
答案匯總:
(
rivershan)
程序員在建立一個(gè)
DLL文件時(shí),鏈接程序會(huì)
自動(dòng)生成一個(gè)與之對(duì)應(yīng)的LIB導(dǎo)入文件。該文件包含了每一個(gè)DLL導(dǎo)出
函數(shù)的符號(hào)名和可選的標(biāo)識(shí)號(hào),但是并不含有實(shí)際的
代碼。LIB文件作為DLL的替代文件被編譯到
應(yīng)用程序
項(xiàng)目中。
當(dāng)程序員通過(guò)靜態(tài)鏈接方式編譯生成應(yīng)用程序時(shí),應(yīng)用程序中的調(diào)用函數(shù)與LIB文件中導(dǎo)出符號(hào)相匹配,這些符號(hào)或標(biāo)識(shí)號(hào)進(jìn)入到生成的EXE文件中。LIB文件中也包含了對(duì)應(yīng)的DLL文件名(但不是完全的路徑名),鏈接程序?qū)⑵浯鎯?chǔ)在EXE文件內(nèi)部。當(dāng)應(yīng)用程序運(yùn)行過(guò)程中需要加載DLL文件時(shí),Windows根據(jù)這些信息發(fā)現(xiàn)并加載DLL,然后通過(guò)符號(hào)名或標(biāo)識(shí)號(hào)實(shí)現(xiàn)對(duì)DLL函數(shù)的動(dòng)態(tài)鏈接。所有被應(yīng)用程序調(diào)用的DLL文件都會(huì)在應(yīng)用程序EXE文件加載時(shí)被加載在到內(nèi)存中??蓤?zhí)行程序鏈接到一個(gè)包含DLL輸出函數(shù)信息的輸入庫(kù)文件(.LIB文件)。操作
系統(tǒng)在加載使用可執(zhí)行程序時(shí)加載DLL。可執(zhí)行程序直接通過(guò)函數(shù)名調(diào)用DLL的輸出函數(shù),調(diào)用方法和程序內(nèi)部其他的函數(shù)是一樣的。
(
stonespace)
調(diào)用dll的export函數(shù)是不需要lib的,dll本身就是和lib同一個(gè)級(jí)別的東西,也提供類似的功能,調(diào)用dll函數(shù)只需要loadlibrary就行,但是你也發(fā)現(xiàn),用loadlibrary很麻煩,要取出函數(shù)的地址,然后還要定義一個(gè)調(diào)用的原型。用dll比用靜態(tài)鏈接庫(kù)lib要麻煩得多。
微軟為了
解決這個(gè)問(wèn)題,在編譯dll的時(shí)候,順便生成一個(gè)引入庫(kù)lib文件,這個(gè)lib不包含實(shí)際功能代碼,只不過(guò)用來(lái)幫你做那些loadlibrary的麻煩工作,讓你用dll和用一般的lib一樣方便。
dll改過(guò)之后,只要export函數(shù)的聲明沒(méi)有修改,也就是參數(shù)、函數(shù)名、返回值沒(méi)有發(fā)生變化,調(diào)用代碼不需要重新編譯。不過(guò)export函數(shù)聲明修改過(guò)就必須重編譯。
(
alphapiao)
使用動(dòng)態(tài)dll有兩種方法,一種是隱式鏈接,一種顯示鏈接,如果用loadlibrary就是顯示鏈接,用lib就屬于隱式鏈接。
(另外找到的)
dll是個(gè)編譯好的程序,
調(diào)用時(shí)可以直接調(diào)用其中的函數(shù),
不參加工程的編譯.
而lib應(yīng)該說(shuō)是一個(gè)程序集,
只是把一些相應(yīng)的函數(shù)總結(jié)在一起,
如果調(diào)用lib中的函數(shù),
在工程編譯時(shí),這些調(diào)用的函數(shù)都將參加編譯.
簡(jiǎn)單講,靜態(tài)庫(kù)就是直接將需要的代碼連接進(jìn)可執(zhí)行程序;動(dòng)態(tài)庫(kù)就是在需要調(diào)用其中的函數(shù)時(shí),根據(jù)函數(shù)映射表找到該函數(shù)然后調(diào)入堆棧執(zhí)行。
做成靜態(tài)庫(kù)可執(zhí)行文件本身比較大,但不必附帶動(dòng)態(tài)庫(kù)
做成動(dòng)態(tài)庫(kù)可執(zhí)行文件本身比較小,但需要附帶動(dòng)態(tài)庫(kù)
其它沒(méi)有什么對(duì)于程序員而言很大的區(qū)別
有的Unix可能不支持動(dòng)態(tài)庫(kù),所以只好用靜態(tài)庫(kù)
DLL與LIB的區(qū)別:
1.DLL是一個(gè)完整程序,其已經(jīng)經(jīng)過(guò)鏈接,即不存在同名引用,且有導(dǎo)出表,與導(dǎo)入表
lib是一個(gè)代碼集(也叫函數(shù)集)他沒(méi)有鏈接,所以lib有冗余,當(dāng)兩個(gè)lib相鏈接時(shí)地址會(huì)重新建立,當(dāng)然還有其它相關(guān)的不同,用lib.exe就知道了
2.在生成dll時(shí),經(jīng)常會(huì)生成一個(gè).lib(導(dǎo)入與導(dǎo)出),這個(gè)lib實(shí)際上不是真正的函數(shù)集,其每一個(gè)導(dǎo)出導(dǎo)入函數(shù)都是跳轉(zhuǎn)指令,直接跳轉(zhuǎn)到DLL中的位置,這個(gè)目的是外面的程序調(diào)用dll時(shí)自動(dòng)跳轉(zhuǎn)
3.實(shí)際上最常用的lib是由lib.exe把*.obj生成的lib,這才是真正的