什麼是dll:
dll只是一組源**的模組,每個模組包含一些可**用程式或者其他dll呼叫的函式,在應用程式呼叫乙個dll裡面的函式的時候,作業系統會將dll的檔案映像對映到程序的位址空間中,這樣程序中所有的執行緒就可以呼叫dll中的函式了
dll載入完成後,這個時候dll對於程序中的執行緒來說只是一些被放在位址程序空間附加的**和資料,作業系統為了節省記憶體空間,同乙個dll在記憶體中只有乙個,也就是說如果你的的兩個應用程式都需要載入user32.dll,那麼作業系統也只會載入一次user32.dll到記憶體中
示例**:
mylib.h
1mylib.cpp#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)
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 ...