2010-07-14 176 views

回答

89

對於靜態庫,.lib文件包含庫的所有代碼和數據。鏈接器然後識別它需要的位並將它們放入最終的可執行文件中。

對於動態庫,.lib文件包含從庫中導出的函數和數據元素的列表以及它們來自哪個DLL的信息。當鏈接器構建最終的可執行文件時,如果使用了庫中的任何函數或數據元素,那麼鏈接器會添加一個對DLL的引用(使其被Windows自動加載),並將條目添加到可執行文件的導入表中對該函數的調用被重定向到該DLL中。

您不需要.lib文件來使用動態庫,但是沒有一個不能將DLL中的函數視爲代碼中的常規函數​​。相反,您必須手動調用LoadLibrary來加載DLL(完成時爲FreeLibrary),並且GetProcAddress可以獲取DLL中函數或數據項的地址。然後您必須將返回的地址轉換爲適當的指針函數以便使用它。

+1

經過漫長的搜索後,國際海事組織,我得到了使用lib和dll的原因的最佳答案。謝謝 – Jeet 2016-02-19 08:30:41

6

在靜態庫中,lib文件包含庫提供的函數的實際目標代碼。在共享版本(您稱爲靜態鏈接動態庫)中,只有足夠的代碼可以在運行時建立動態鏈接。

我不確定「動態鏈接動態庫」(以編程方式加載)。在這種情況下你甚至可以鏈接到.lib文件嗎?

編輯:

有點姍姍來遲,但沒有,你不鏈接的.lib。那麼,你可以通過libraryloaderex鏈接到lib。但是,對於您正在使用的實際庫,通過C函數指針提供自己的綁定和調用LoadLibrary填補那些

這裏有一個總結:

 
Linking ǁ Static  | DLL     | LoadLibrary 
=========ǁ===============|======================|=================== 
API code ǁ In your com- | In the DLL   | In the DLL 
lives ǁ piled program |      | 
---------ǁ---------------|----------------------|------------------- 
Function ǁ Direct, may | Indirect via table | Indirect via your 
calls ǁ be elided  | filled automatically | own function ptrs 
---------ǁ---------------|----------------------|------------------- 
Burden ǁ Compiler  | Compiler/OS   | You/OS 
+0

通過靜態鏈接庫,我的意思是使用.lib文件並在編譯時鏈接.dll。動態鏈接使用Win32 API的libraryloaderex()函數在運行時鏈接.dll。 – Sulla 2010-07-14 21:07:26

1

在DLL的是「東西」就像在一個exe (可以有任何種類的數據,導入,導出,讀/寫/可執行部分),但區別在於exe文件只導出入口點(函數),但dll導出一個/多個函數。

8

我發現下面這個漢斯的answer在這裏也很有用。它清除了可能有兩種類型的lib文件的空氣。

一個LIB文件用於構建您的程序,它只存在於您的構建 機器上,並且您不運送它。有兩種。靜態鏈接 庫是一包.obj文件,收集到一個文件中。當需要解析 外部標識符時, 鏈接器會從文件中選取任何代碼塊。

但與DLL更相關,LIB文件也可以是導入庫。 然後它是一個簡單的小文件,其中包含DLL的名稱和DLL導出的所有函數的列表。當您構建使用DLL的程序時,您需要提供 它給鏈接器,因此它 知道外部標識符實際上是由DLL的 導出的函數。鏈接器使用導入庫將條目添加到EXE的 導入表中。然後Windows又利用它在 運行時找出需要加載哪些DLL來運行程序。

1

鏈接器讀取lib文件並在執行過程中使用dll文件。一個lib文件在執行期間基本上是無用的,並且鏈接器不能從讀取一個dll文件(除非可能以這裏無關的方式)。

使用lib文件進行靜態鏈接和動態鏈接的區別可能會讓人困惑,但如果您瞭解了一些歷史記錄,就會變得非常清楚。

最初只有靜態庫。對於靜態庫,.lib文件包含obj文件。每個obj文件都是唯一一個編譯器源代碼輸入文件的輸出。 lib文件只是一個相關obj文件的集合,就像將obj文件放在一個目錄中一樣。這實質上就是一個lib文件,一個obj文件庫。對於靜態鏈接,可執行文件使用的所有obj文件都合併爲一個文件。將其與可執行文件與其使用的其他代碼分開的文件中的動態鏈接進行比較。

爲了實現動態鏈接,Microsoft修改了lib文件的使用,以便它們引用dll文件而不是obj文件中的位置。除此之外,靜態鏈接庫中的所有信息與動態鏈接相同。除了動態鏈接的lib文件指定了dll文件外,它們和它們中的信息一樣。