動態鏈接庫dll,靜態鏈接庫lib, 導入庫lib

目前以lib後綴的庫有兩種,一種爲靜態鏈接庫(Static Libary,以下簡稱“靜態庫”),另一種爲動態連接庫(DLL,以下簡稱“動態庫”)的導入庫(Import Libary,以下簡稱“導入庫”)。
靜態庫是一個或者多個obj文件的打包,所以有人乾脆把從obj文件生成lib的過程稱爲Archive,即合併到一起。比如你鏈接一個靜態庫,如果其中有錯,它會準確的找到是哪個obj有錯,即靜態lib只是殼子。
動態庫一般會有對應的導入庫,方便程序靜態載入動態鏈接庫,否則你可能就需要自己LoadLibary調入DLL文件,然後再手工GetProcAddress獲得對應函數了。有了導入庫,你只需要鏈接導入庫後按照頭文件函數接口的聲明調用函數就可以了。
導入庫和靜態庫的區別很大,他們實質是不一樣的東西。靜態庫本身就包含了實際執行代碼、符號表等等,而對於導入庫而言,其實際的執行代碼位於動態庫中,導入庫只包含了地址符號表等,確保程序找到對應函數的一些基本地址信息

這也是實際上很多開源代碼發佈的慣用方式:

1. 預編譯的開發包:包含一些.dll文件和一些.lib文件。其中這裏的.lib就是導入庫,而不要錯以爲是靜態庫。但是引入方式和靜態庫一樣,要在鏈接路徑上添加找到這些.lib的路徑。而.dll則最好放到最後產生的應用程序exe執行文件相同的目錄。這樣運行時,就會自動調入動態鏈接庫。

2. 用戶自己編譯: 下載的是源代碼,按照readme自己編譯。生成很可能也是.dll + .lib(導入庫)的庫文件

3. 如果你只有dll,並且你知道dll中函數的函數原型,那麼你可以直接在自己程序中使用LoadLibary調入DLL文件,GetProcAddress

DLL:
動態鏈接庫 (DLL) 是作爲共享函數庫的可執行文件。動態鏈接提供了一種方法,使進程可以調用不屬於其可執行代碼的函數。函數的可執行代碼位於一個 DLL 中,該 DLL 包含一個或多個已被編譯、鏈接並與使用它們的進程分開存儲的函數。DLL 還有助於共享數據和資源。多個應用程序可同時訪問內存中單個 DLL 副本的內容。
動態鏈接與靜態鏈接的不同之處在於它允許可執行模塊(.dll 文件或 .exe 文件)僅包含在運行時定位 DLL 函數的可執行代碼所需的信息。在靜態鏈接中,鏈接器從靜態鏈接庫獲取所有被引用的函數,並將庫同代碼一起放到可執行文件中。
使用動態鏈接代替靜態鏈接有若干優點。DLL 節省內存,減少交換操作,節省磁盤空間,更易於升級,提供售後支持,提供擴展 MFC 庫類的機制,支持多語言程序,並使國際版本的創建輕鬆完成。

、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、

靜態鏈接舉例用的.lib其實是win特有的,屬於歷史遺留問題,這樣鏈接的庫最後再運行時仍然是加載的.dll,只不過是由系統完成裝配。而靜態鏈接則是你說的第一種,鏈接完成後就不需要庫文件也可以執行了。完全是Win的鏈接方式把你搞迷糊了,考慮一下linux/unix平臺就知道了,靜態庫.a,動態庫.so,沒有第三種形態。動態庫也可不鏈接動態載入。可以說鏈接有兩種形式,靜態和動態。動態庫載入有兩種方式,執行時系統裝配運行時動態載入。不能混爲一談。

。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。

可以說windows提供了三種方法:
1.Use static libary 此時被調用函數的代碼將會被打包進可執行文件。

2.static linked DLL 此時動態連接庫(DLL,“動態庫”)的導入庫(Import Libary,“導入庫”)將會被打包入可執行文件,而動態庫(包含有被調用函數的代碼實現)將會在程序被加載到內存時加載到內存

3. dynamic linked DLL,僅在程序需要時加載被調用函數的代碼實現到內存,且可隨時卸載。故比方法2節省內存。

方法1,2打包進去的都是lib文件,但他們是不同的。lib文件有兩種,靜態庫(static libary) 和dll的導入庫(importlibary)。前者是有函數實現的,後者沒有。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章