什麼是動態鏈結庫

2021-09-27 03:42:57 字數 2685 閱讀 2570

什麼是dll:

dll只是一組源**的模組,每個模組包含一些可**用程式或者其他dll呼叫的函式,在應用程式呼叫乙個dll裡面的函式的時候,作業系統會將dll的檔案映像對映到程序的位址空間中,這樣程序中所有的執行緒就可以呼叫dll中的函式了

dll載入完成後,這個時候dll對於程序中的執行緒來說只是一些被放在位址程序空間附加的**和資料,作業系統為了節省記憶體空間,同乙個dll在記憶體中只有乙個,也就是說如果你的的兩個應用程式都需要載入user32.dll,那麼作業系統也只會載入一次user32.dll到記憶體中

示例**:

mylib.h

1

#ifdef mylibapi

2#else

3#define mylibapi extern "c" __desclspec(dllimport)

4#endif

56 mylibapi int

g_nresult;

78 mylibapi int add(int nleft,int nright)

mylib.cpp

1 #include 2

3#define mylibapi extern "c" __declspec(dllexport)

4 #include "

mylib.h"5

intg_nresult;67

int add(int nleft,int

nright)

8

輸入命令:

cl /ldd mylib.cpp

可以生成可供除錯的dll

這個時候會多出四個檔案,分別是mylib.exp,mylib.lib,mylib.dll,mylib.obj

mylib.obj儲存的是在鏈結器生成dll的需要的資訊

當鏈結器檢測到應用程式匯出了乙個函式或者變數,鏈結器就會生成mylib.lib檔案,這個只是列出了匯出的函式和變數的符號名

輸入命令檢視lib裡面的匯出段

我們可以看到這個lib裡面export了_add和_g_nresult

如果我們使用dumpbin -imports mylib.lib

imports裡面沒有變數或者函式,這是因為lib裡面記錄的只是匯出的函式和變數,只有在宣告有匯出函式或者變數的時候,才會生成這個檔案

mylib.dll則是我們最終生成的模組

如果使用dumpbin檢視mylib.dll的匯出

匯入則因為太多,所以不貼出來

到我們需要將乙個函式匯出的時候,可以使用__desclspec(dllexport)來宣告為匯出函式,需要從dll使用乙個函式的時候,可以使用__desclspecc(dllimport)來前置宣告乙個函式,當然,也可以不使用import前置宣告,但是使用improt可以明確告訴編譯器這些函式是從dll匯入的,提高效率

什麼是匯出?

當將函式或者變數宣告為匯出後,編譯器在生成obj的時候會嵌入一些額外的資訊,以便於讓鏈結器在生成dll的時候使用,並且會生成乙個記錄匯出函式和變數的lib檔案,在生成可執行檔案的時候,我們需要通過鏈結這個lib來取得dll的一些資訊,鏈結器在生成dll的時候,會在dll檔案中嵌入乙個匯出符號表,這個符號表記錄了匯出的函式和變數的符號名,並且儲存對應的檔案偏移量位址,這樣當可執行檔案需要呼叫dll裡面的函式的時候,可以通過這個符號表來找到對應函式的位址

最後我們開始構建可執行檔案,**如下

myexe.cpp

#include

#include "mylib.h"

int main(void)

cl myexe.cpp mylib.lib

我們在編譯的時候一定要鏈結mylib.lib,這樣編譯器才知道要到**去找mylib的變數和函式相關資訊,並且可執行檔案也才知道程式需要mylib.dll這個dll,這樣程式在載入的時候會搜尋使用者磁碟上的dll,如果沒找到則會報錯,找到則將dll對映到程序的記憶體空間裡面

當dll對映到程序的記憶體空間裡面後,引導程式會檢視在對應的dll的匯出段符號是否存在,如果不存在,則報錯,如果存在,那麼引導程式會將該符號載入到該符號的所在的檔案偏移量(rva,虛擬位址,但在dll裡面實際上是該符號所在檔案的位置),加上該dll載入的虛擬位址,儲存到可執行程式的匯入段中,當**引用到匯入符號的時候,可執行檔案會去檢視匯入段並且得到匯入符號的位址,這樣就能訪問匯入的變數或者函式

例如我們生成的mylib.dlll檔案,利用dumpbin可以得到輸出:

我們可以看到add的rva是1000,假設我們的dll被應用程式對映到1000的位址空間中,那麼在應用程式執行的時候,add函式最終會被載入到1000+1000即2000處,這個就是我們前面所說的dll在對映到位址空間後,對於應用程式來說不過是一堆附加的**和資料

什麼是動態鏈結庫

什麼是dll dll只是一組源 的模組,每個模組包含一些可 用程式或者其他dll呼叫的函式,在應用程式呼叫乙個dll裡面的函式的時候,作業系統會將dll的檔案映像對映到程序的位址空間中,這樣程序中所有的執行緒就可以呼叫dll中的函式了 dll載入完成後,這個時候dll對於程序中的執行緒來說只是一些被...

動態鏈結庫 靜態鏈結庫

包含標頭檔案和庫 idir 指定編譯查詢標頭檔案的目錄,常用於查詢第三方的庫的標頭檔案,例 gcc test.c i.inc o test。ldir 指定鏈結時查詢lib的目錄,常用於查詢第三方庫。llibrary 指定額外鏈結的lib庫 巨集定義 dmacro 以字串 1 預設值 定義 macro...

靜態鏈結庫 動態鏈結庫

庫是寫好的現有的,成熟的,可以復用的 現實中每個程式都要依賴很多基礎的底層庫,不可能每個人的 都從零開始,因此庫的存在意義非同尋常。本質上來說庫是一種可執行 的二進位制形式,可以被作業系統載入記憶體執行。庫有兩種 靜態庫 a lib 和動態庫 so dll windows上對應的是.lib dll ...