呼叫乙個dll中的函式有兩種方法:
1)載入時動態鏈結(load-time dynamic linking)
模組非常明確自己要呼叫哪些匯出函式,使得它們就像本地函式一樣。要達到如此,需要鏈結時鏈結那些匯出函式所在dll的導入庫,導入庫向系統提供了載入dll時所需的資訊(庫的符號鏈結之類)及dll函式定位(匯入的函式資訊)。
載入時動態鏈結就是在生成可執行檔案的時候把庫的符號鏈結及匯出函式表(包含各個函式的資訊)寫入到可執行檔案中,然後程式載入時,系統根據這些資訊來找它需要的動態庫,確定程式中使用的庫中的**在什麼位置。
2)執行時動態鏈結(run-time dynamic linking)
執行時windows可以通過loadlibrary或loadlibraryex函式載入dll,linux可以通過dlopen函式載入dll。dll載入後,windows中模組可以通過呼叫getprocaddress/linux中可以通過呼叫dlsym來獲取dll函式的出口位址,然後就可以通過返回的函式指標呼叫dll函式了。如此即可避免導入庫檔案了。
另外,順便介紹dll中匯出函式的宣告的兩種方式:
一種方式是:在函式宣告中加上__declspec(dllexport);
另外一種方式是:採用模組定義(.def)檔案宣告,(.def)檔案為鏈結器提供了有關被鏈結程式的匯出、屬性及其他方面的資訊。
方式一:在函式宣告中加上__declspec(dllexport)
/// 在動態鏈結庫程式中
/// 宣告動態鏈結庫(**.dll)的對外介面函式testfuction
extern "c" __declspec(dllexport) int testfuction(int ntype,char *strpath,std::vector&vecdata)
/// 在外部希望呼叫動態鏈結庫的程式中
/// 載入動態鏈結庫(**.dll)並呼叫其對外介面testfuction
void func()
//定義乙個與函式testfuction型別相同的函式指標lpproc
testdll lpproc;
//搜尋**.dll中函式名為testfuction的對外介面
lpproc = (testdll)getprocaddress (hmod,"testfuction");
//如果搜尋成功
if(null != lpproc)
//...
//在恰當的時候釋放動態鏈結庫**.dll
freelibrary(hmod);
}方式二:採用模組定義(.def)檔案宣告
首先建立 乙個dll程式(dlltestdef)
在*.cpp中
int __stdcall add(int numa, int numb)
int __stdcall sub(int numa, int numb)
然後建立乙個.def的檔案,在裡面加上
最後建立乙個測試程式:.cpp檔案如下:
#include
#include
using namespace std;
typedef int (__stdcall *fun)(int, int);
hinstance hinstance;
fun
fun;
int main()
cout << fun(1, 2) << endl;
freelibrary(hinstance);
return 0;
}說明:
.def檔案的規則為:
(1)library語句說明.def檔案相應的dll;
(2)exports語句後列出要匯出函式的名稱。可以在.def檔案中的匯出函式名後加@n,表示要匯出函式的序號為n(在進行函式呼叫時,這個序號將發揮其作用);
(3).def 檔案中的注釋由每個注釋行開始處的分號 (;) 指定,且注釋不能與語句共享一行。
(4)使用__declspec(dllexport)和使用.def檔案是有區別的。
如果你的dll是提供給vc使用者使用的,你只需要把編譯dll時產生的.lib提供給使用者,
它可以很輕鬆地呼叫你的dll。但是如果你的dll是供vb、pb、delphi使用者使用的,那麼會產生乙個小麻煩。
因為vc++編譯器對於__declspec(dllexport)宣告的函式會進行名稱轉換,如下面的函式:
__declspec(dllexport) int __stdcall add()
會轉換為add@0
,這樣你在vb中必須這樣宣告:
declare function add lib "dlltestdef.dll" alias "add@0
" () as long
@後面的數由於引數型別不同而可能不同。這顯然不太方便。所以如果要想避免這種轉換,就要使用.def檔案方式匯出函式了。
動態鏈結庫的兩種方式
呼叫乙個dll中的函式有兩種方法 1 載入時動態鏈結 load time dynamic linking 模組非常明確自己要呼叫哪些匯出函式,使得它們就像本地函式一樣。要達到如此,需要鏈結時鏈結那些匯出函式所在dll的導入庫,導入庫向系統提供了載入dll時所需的資訊 庫的符號鏈結之類 及dll函式定...
Delphi中動態鏈結庫兩種呼叫方式的比較
摘要 本文闡述了windows環境下動態鏈結庫的概念和特點,對靜態呼叫和動態呼叫兩種呼叫方式作出了比較,並給出了delphi中應用動態鏈結庫的例項。動態鏈結庫 dynamic link library,縮寫為dll 是乙個可以被其它應用程式共享的程式模組,其中封裝了一些可以被共享的例程和資源。動態鏈...
動態鏈結庫呼叫方式
首先來說說呼叫的原理 呼叫dll,首先需要將dll檔案映像到使用者程序的位址空間中,然後才能進行函式呼叫,這個函式和程序內部一般函式的呼叫方法相同。windows提供了兩種將dll映像到程序位址空間的方法 隱式呼叫 通過lib和標頭檔案 和顯式呼叫 只通過提供的dll檔案 下面對這兩種方式在vc中如...