動態鏈結庫dll學習總結

2021-05-31 00:29:14 字數 4349 閱讀 8362

1. 什麼是lib檔案,lib和dll的關係如何

(1)lib是編譯時需要的,dll是執行時需要的。

如果要完成源**的編譯,有lib就夠了。

如果也使動態連線的程式執行起來,有dll就夠了。

在開發和除錯階段,當然最好都有。

(2)一般的動態庫程式有lib檔案和dll檔案。lib檔案是必須在編譯期就連線到應用程式中的,而dll檔案是執行期才會被呼叫的。如果有dll檔案,那麼對應的lib檔案一般是一些索引資訊,具體的實現在dll檔案中。

如果只有lib檔案,那麼這個lib檔案是靜態編譯出來的,索引和實現都在其中。靜態編譯的lib檔案有好處:給使用者安裝時就不需要再掛動態庫了。

但也有缺點,就是導致應用程式比較大,而且失去了動態庫的靈活性,在版本公升級時,同時要發布新的應用程式才行。

(3)在動態庫的情況下,有兩個檔案,乙個是引入庫(.lib)檔案,乙個是dll檔案,引入庫檔案包含被dll匯出的函式的名稱和位置,dll包含實際的函式和資料,應用程式使用lib檔案鏈結到所需要使用的dll檔案,dll庫中的函式和資料並不複製到可執行檔案中,因此在應用程式的可執行檔案中,存放的不是被呼叫的函式**,而是dll中所要呼叫的函式的記憶體位址,這樣當乙個或多個應用程式執行時再把程式**和被呼叫的函式**鏈結起來,從而節省了記憶體資源。從上面的說明可以看出,dll和.

lib檔案必須隨應用程式一起發行,否則應用程式將會產生錯誤。

2、嚴重警告:

(1) 用 extern "c" _declspec(dllexport) 只可以匯出全域性函式,不能匯出類的成員函式

(2) 使用extern "c" _declspec(dllexport)輸出的函式可以被c語言呼叫,否則則不可

(3) 注意標準呼叫約定的問題,輸出與呼叫的函式約定應該一致,如當dll模組的函式輸出採用標準呼叫約定_stdcall,則呼叫程式的匯入函式說明也要用標準約定

(4) 用extern "c" _declspec(dllexport) 和 expotrt匯出的函式不改變函式名,可以給c++或c編寫的exe呼叫.

假如沒有extern "c",匯出的函式名將會改變,只能給c++編寫的exe呼叫

(5)在動態載入動態鏈結庫函式時注意getprocaddress(hinst,"add")中第二個引數是否為動態鏈結庫匯出的函式名,因為在生成動態庫時可能會改變動態庫匯出函式的函式名,加上修飾符

(6)dll初始化全域性變數時,全域性變數要放在共享資料斷,並且初始化每乙個變數,在starthook函式裡初始化其值,記得一進函式就初始化

(7)除錯時,編譯器會自動查詢其目錄下(不含debug和release目錄)的dll檔案,所以dll檔案應該放在主檔案目錄下,但生成的應用程式則只會在同乙個目錄下找dll(不需要lib檔案),所以單純的執行exe,不通過編譯器,那就要把dll檔案放在與exe相同的目錄下

(8)用#pragma ***ment(lib,"dlltest.lib")匯入lib檔案,不需要在設定裡修改

(9) dll裡的指標變數不要用new

dll 呼叫方式

dll(動態連線庫),可以分為動態調用於靜態呼叫。下面我分別舉乙個例子說說。

1)動態呼叫:

首先:在vc++6.0中建立 win32 dynamic-link library工程建立乙個動態連線庫工程:

在標頭檔案testdll.h中寫下**

extern "c" int __declspec(dllexport) add(int numa, int numb);//宣告匯出函式

在原始檔testdll.cpp中實現改函式:

int __declspec(dllexport) add(int numa, int numb)

return numa + numb;

然後,建立乙個測試程式,testdemo,建立乙個.cpp檔案,然後放下**:

hinstance hinstance;

typedef int (*lpadd)(int a, int b);

lpadd lpadd;

int main()

下面我們來逐一分析。

首先,語句typedef int ( * lpaddfun)(int,int)定義了乙個與add函式接受引數型別和返回值均相同的函式指標型別。隨後,在main函式中定義了lpaddfun的例項addfun;

其次,在函式main中定義了乙個dll hinstance控制代碼例項hdll,通過win32 api函式loadlibrary動態載入了dll模組並將dll模組控制代碼賦給了hdll;

再次,在函式main中通過win32 api函式getprocaddress得到了所載入dll模組中函式add的位址並賦給了addfun。經由函式指標addfun進行了對dll中add函式的呼叫;

最後,應用工程使用完dll後,在函式main中通過win32 api函式freelibrary釋放了已經載入的dll模組。

通過這個簡單的例子,我們獲知dll定義和呼叫的一般概念:

(1)dll中需以某種特定的方式宣告匯出函式(或變數、類);

(2)應用工程需以某種特定的方式呼叫dll的匯出函式(或變數、類)。

2)靜態連線:

**如下:

#include

using namespace std;

#pragma ***ment(lib,"testlib.lib")

//.lib檔案中僅僅是關於其對應dll檔案中函式的重定位資訊

extern "c" __declspec(dllimport) add(int x,int y);//宣告匯入函式

int main()

注意:(1)、在編寫dll檔案時,必須以某種方式宣告匯出函式(dll檔案內有匯出函式和內部函式兩種,內部函式供dll內部呼叫),可以用自定義模組檔案(.def檔案)來宣告匯出函式,也可以使用_declspec(dllexport)字首來宣告匯出函式。

檔案除了宣告匯出函式之外還可以消除函式修飾符的影響,並產生動態鏈結庫導入庫(.lib檔案)

(2)、在顯示呼叫dll時,只需要.dll檔案即可,而且只能通過函式指標來呼叫dll中的匯出函式。

在隱式呼叫dll時,要將相應的.lib檔案加入到工程中,並且在呼叫dll的匯出函式之前,必須對使用的函式進行宣告(或者包含進相應的dll檔案的標頭檔案也可)。

(3)、.def檔案只在生成dll的過程中起作用,在應用程式呼叫dll時,不起作用。

dll的呼叫方法

1. 動態鏈結庫(dynamic link library),簡稱dll。dll 是乙個包含可由多個程式同時使用的**和資料的庫。

它允許程式共享執行特殊任務所必需的**和其他資源,一般來說,dll是一種磁碟檔案,以.dll、.drv、.

fon、.sys和許多以.exe為副檔名的系統檔案都可以是dll。

它由全域性資料、服務函式和資源組成,在執行時被系統載入到呼叫程序的虛擬空間中,成為呼叫程序的一部分。dll的呼叫可以分為兩種:一種是隱式呼叫,一種是顯示呼叫這裡簡單分享dll的兩種呼叫方法。

隱式的呼叫

這種呼叫方式需要把產生動態連線庫時產生的.lib檔案加入到應用程式的工程中,在使用dll中的函式時,只須宣告一下後就可以直接通過函式名呼叫dll的輸出函式,呼叫方法和程式內部其他的函式是一樣的。隱式呼叫不需要呼叫loadlibrary()和freelibrary()。

程式設計師在建立乙個dll檔案時,鏈結程式會自動生成乙個與之對應的lib匯入檔案。該檔案包含了每乙個dll匯出函式的符號名和可選的標識號,但是並不含有實際的**。lib檔案作為dll的替代檔案被編譯到應用程式專案中。

當程式設計師通過隱式呼叫方式編譯生成應用程式時,應用程式中的呼叫函式與lib檔案中匯出符號相匹配,這些符號或標識號被寫入到生成的exe檔案中。lib檔案中也包含了對應的dll檔名(但不是完全的路徑名),鏈結程式也將其儲存在exe檔案內部。當應用程式執行過程中需要載入dll檔案時,windows根據這些資訊發現並載入dll,然後通過符號名或標識號實現對dll函式的動態鏈結。

所有被應用程式呼叫的dll檔案都會在應用程式exe檔案載入時被載入在到記憶體中。

顯式呼叫

,並指定dll的路徑作為引數。loadlibary返回hinstance引數,應用程式在呼叫getprocaddress函式時使用這一引數。當完成對動態鏈結庫的匯入以後,再使用getprocaddress()獲取想要引入的函式,該函式將符號名或標識號轉換為dll內部的位址,之後就可以象使用本應用程式自定義的函式一樣來呼叫此引入函式了。

在應用程式退出之前,應該用freelibrary或mfc提供的afxfreelibrary釋放動態連線庫。

dll的優點

簡單的說,dll有以下幾個優點:

1) 節省記憶體。同乙個軟體模組,若是以源**的形式重用,則會被編譯到不同的可執行程式中,同時執行這些exe時這些模組的二進位製碼會被重複載入到記憶體中。如果使用dll,則只在記憶體中載入一次,所有使用該dll的程序會共享此塊記憶體(當然,像dll中的全域性變數這種東西是會被每個程序複製乙份的)。

靜態鏈結庫與動態鏈結庫區別

動態鏈結庫 dll不必被包含在最終的exe中,exe檔案執行時可以動態地引用和解除安裝dll檔案。同時,靜態鏈結庫中不能再包含其他的動態鏈結庫或靜態庫,而動態鏈結庫中可以包含其他的動態或靜態庫。vc 支援的dll dll的編制與具體的程式語言及編譯器無關,動態鏈結庫隨處可見,vc 支援三種dll 非...

第十四章動態鏈結庫

第十四章動態鏈結庫 visual c 6.0 程式設計例項與技巧 一建立s14 dll 1 這個擴充套件mfc extension dll 向應用程式提供的功能有 1 建立工程 2 設計共享資料 pragma data seg myshareddata 宣告乙個共享資料段用於程序使用dll的記數 i...

linux下動態庫靜態庫鏈結路徑設定問題

g gcc 連線 so動態庫或者 a靜態庫時,需要設定這些動態庫的路徑,例如 g o main l.lib ldymamic lpthread lrt 這些是設定到哪個目錄下去查詢關聯的動態庫。如果在 l目錄下面找不到相應的動態庫,就會到 ld library path 的目錄下去找,如果還找不到,...