Windows C++ 導出和導入純DLL函數(非COM)總結
多年以前由於DLL hell 問題人們很少在直接從dll文件導出函數並且直接使用,但是有時候事情的解決方案不是我們可以選擇的,今天在解決一個問題的時候,還是不得已選擇了一個這樣的方式。但是搜索了一下,網上關於這個問題的總結文章都寫的不是很全,於是總結出來,希望對大家有所幫助。
靜態導入和動態導入加起來一共三種方式 :
靜態導入 --需要將 .lib文件和.dll文件copy到執行目錄
1. dllexport導出 dllimport導入。
導出時這樣寫:
__declspec( dllexport ) void func(void){}
導入時這樣寫:
__declspec( dllimport ) void func(void);
2. .def文件導出dllimport導入。
關於.def的說明:
.def 文件是包含一個或多個描述 DLL 各種屬性的 Module 語句的文本文件。如果不使用 __declspec(dllexport) 關鍵字導出 DLL 的函數,則 DLL 需要 .def 文件。.def 文件必須至少包含下列模塊定義語句:
文件中的第一個語句必須是 LIBRARY 語句。此語句將 .def 文件標識為屬於 DLL。LIBRARY 語句的后面是 DLL 的名稱。鏈接器將此名稱放到 DLL 的導入庫中。
EXPORTS 語句列出名稱,可能的話還會列出 DLL 導出函數的序號值。通過在函數名的后面加上 @ 符和一個數字,給函數分配序號值。當指定序號值時,序號值的范圍必須是從 1 到 N,其中 N 是 DLL 導出函數的個數。
動態導入--需要將.dll文件copy到執行目錄
3. LoadLibrary(),GetProcAddress(),FreeLibrary() 慣用法。
示例代碼:
...
HINSTANCE hDLL; // Handle to DLL
LPFNDLLFUNC1 lpfnDllFunc1; // Function pointer
DWORD dwParam1;
UINT uParam2, uReturnVal;
hDLL = LoadLibrary( " MyDLL ");
if (hDLL != NULL)
{
lpfnDllFunc1 = (LPFNDLLFUNC1)GetProcAddress(hDLL,
" DLLFunc1 ");
if (!lpfnDllFunc1)
{
// handle the error
FreeLibrary(hDLL);
return SOME_ERROR_CODE;
}
else
{
// call the function
uReturnVal = lpfnDllFunc1(dwParam1, uParam2);
}
}