LIB和DLL的區別與使用

2021-06-22 13:29:32 字數 3330 閱讀 2878

【原文】

共有兩種庫:

一種是lib包含了函式所在的dll檔案和檔案中函式位置的資訊(入口),**由執行時載入在程序空間中的dll提供,稱為動態鏈結庫dynamic link library。

一種是lib包含函式**本身,在編譯時直接將**加入程式當中,稱為靜態鏈結庫static link library。

共有兩種鏈結方式:

動態鏈結使用動態鏈結庫,允許可執行模組(.dll檔案或.exe檔案)僅包含在執行時定位dll函式的可執行**所需的資訊。

靜態鏈結使用靜態鏈結庫,鏈結器從靜態鏈結庫lib獲取所有被引用函式,並將庫同**一起放到可執行檔案中。

關於lib和dll的區別如下:

(1)lib是編譯時用到的,dll是執行時用到的。如果要完成源**的編譯,只需要lib;如果要使動態鏈結的程式執行起來,只需要dll。

(2)如果有dll檔案,那麼lib一般是一些索引資訊,記錄了dll中函式的入口和位置,dll中是函式的具體內容;如果只有lib檔案,那麼這個lib檔案是靜態編譯出來的,索引和實現都在其中。使用靜態編譯的lib檔案,在執行程式時不需要再掛動態庫,缺點是導致應用程式比較大,而且失去了動態庫的靈活性,發布新版本時要發布新的應用程式才行。

(3)動態鏈結的情況下,有兩個檔案:乙個是lib檔案,乙個是dll檔案。lib包含被dll匯出的函式名稱和位置,dll包含實際的函式和資料,應用程式使用lib檔案鏈結到dll檔案。在應用程式的可執行檔案中,存放的不是被呼叫的函式**,而是dll中相應函式**的位址,從而節省了記憶體資源。dll和lib檔案必須隨應用程式一起發行,否則應用程式會產生錯誤。如果不想用lib檔案或者沒有lib檔案,可以用win32 api函式loadlibrary、getprocaddress裝載。

使用lib需注意兩個檔案:

(1).h標頭檔案,包含lib中說明輸出的類或符號原型或資料結構。應用程式呼叫lib時,需要將該檔案包含入應用程式的原始檔中。

(2).lib檔案,略。

使用dll需注意三個檔案:

(1).h標頭檔案,包含dll中說明輸出的類或符號原型或資料結構的.h檔案。應用程式呼叫dll時,需要將該檔案包含入應用程式的原始檔中。

(2).lib檔案,是dll在編譯、鏈結成功之後生成的檔案,作用是當其他應用程式呼叫dll時,需要將該檔案引入應用程式,否則產生錯誤。如果不想用lib檔案或者沒有lib檔案,可以用win32 api函式loadlibrary、getprocaddress裝載。

(3).dll檔案,真正的可執行檔案,開發成功後的應用程式在發布時,只需要有.exe檔案和.dll檔案,並不需要.lib檔案和.h標頭檔案。

使用lib的方法:

靜態lib中,乙個lib檔案實際上是任意個obj檔案的集合,obj檔案是cpp檔案編譯生成的。在編譯這種靜態庫工程時,根本不會遇到鏈結錯誤;即使有錯,也只會在使用這個lib的ext檔案或者dll工程裡暴露出來。

在vc中新建乙個static library型別的工程lib,加入test.cpp檔案和test.h檔案(標頭檔案內包括函式宣告),然後編譯,就生成了lib.lib檔案。

別的工程要使用這個lib有兩種方式:

(1)在project->link->object/library module中加入lib.lib檔案(先查詢工程目錄,再查詢系統lib目錄);或者在源**中加入指令#pragma comment(lib, 「lib.lib」)。

(2)將lib.lib拷入工程所在目錄,或者執行檔案生成的目錄,或者系統lib目錄中。

(3)加入相應的標頭檔案test.h。

使用dll的方法:

使用動態鏈結中的lib,不是obj檔案的集合,即裡面不會有實際的實現,它只是提供動態鏈結到dll所需要的資訊,這種lib可以在編譯乙個dll工程時由編譯器生成。

建立dll工程的方法(略)。

(1)隱式鏈結

第一種方法是:通過project->link->object/library module中加入.lib檔案(或者在源**中加入指令#pragma comment(lib, 「lib.lib」)),並將.dll檔案置入工程所在目錄,然後新增對應的.h標頭檔案。

#include "stdafx.h"

#include "dllsample.h"

int main()

(2)顯式鏈結

需要函式指標和win32 api函式loadlibrary、getprocaddress裝載,使用這種載入方法,不需要.lib檔案和.h標頭檔案,只需要.dll檔案即可(將.dll檔案置入工程目錄中)。

#include #include //使用函式和某些特殊變數

typedef void (*dllfunc)(int);

int main()

dllfunc = (dllfunc)getprocaddress(hinstlibrary, "testdll");

if (dllfunc == null)

dllfunc(123);

std::cin.get();

freelibrary(hinstlibrary);

return(1);

}

loadlibrary函式利用乙個名稱作為引數,獲得dll的例項(hinstance型別是例項的控制代碼),通常呼叫該函式後需要檢視一下函式返回是否成功,如果不成功則返回null(控制代碼無效),此時呼叫函式freelibrary釋放dll獲得的記憶體。

getprocaddress函式利用dll的控制代碼和函式的名稱作為引數,返回相應的函式指標,同時必須使用強轉;判斷函式指標是否為null,如果是則呼叫函式freelibrary釋放dll獲得的記憶體。此後,可以使用函式指標來呼叫實際的函式。

最後要記得使用freelibrary函式釋放記憶體。

注意:應用程式如何找到dll檔案?

使用loadlibrary顯式鏈結,那麼在函式的引數中可以指定dll檔案的完整路徑;如果不指定路徑,或者進行隱式鏈結,windows將遵循下面的搜尋順序來定位dll:

(1)包含exe檔案的目錄

(2)工程目錄

(3)windows系統目錄

(4)windows目錄

(5)列在path環境變數中的一系列目錄

注意:鏈結庫的對應

如果乙個工程是生成的靜態庫lib,則h檔案中的函式宣告之前沒有匯出巨集,如果是動態庫dll,則函式宣告前有函式匯出巨集,例如:__declspec(dllexport) ,再其他的工程裡面呼叫這個庫時一定要注意對應,否則報鏈結錯誤。

LIB和DLL的區別與使用

共有兩種庫 一種是lib包含了函式所在的dll檔案和檔案中函式位置的資訊 入口 由執行時載入在程序空間中的dll提供,稱為動態鏈結庫dynamic link library。一種是lib包含函式 本身,在編譯時直接將 加入程式當中,稱為靜態鏈結庫static link library。共有兩種鏈結方...

LIB和DLL的區別與使用

共有兩種庫 一種是lib包含了函式所在的dll檔案和檔案中函式位置的資訊 入口 由執行時載入在程序空間中的dll提供,稱為動態鏈結庫dynamic link library。一種是lib包含函式 本身,在編譯時直接將 加入程式當中,稱為靜態鏈結庫static link library。共有兩種鏈結方...

LIB和 DLL的區別與使用

原文在這裡 共有兩種庫 一種是lib 包含了函式所在的 dll檔案和檔案中函式位置的資訊 入口 由執行時載入在程序空間中的 dll提供,稱為動態鏈結庫 dynamic link library 一種是 lib包含函式 本身,在編譯時直接將 加入程式當中,稱為靜態鏈結庫 static link lib...