加載DLL的方法主要有兩種:一種是隱式鏈接,另外一種是動態(tài)加載。
隱式鏈接會把DLL中所有標(biāo)志為_declspec(dllexport)的函數(shù)都加載,如果有多個(gè)DLL加載時(shí),可能會影響到程序執(zhí)行的效率。而用動態(tài)加載DLL的方式則可以根據(jù)需要去加載用到的函數(shù)。
動態(tài)加載DLL的方法:
1.把生成的.DLL文件復(fù)制到測試工程DLLTest目錄下。這里假設(shè)該.DLL文件為add.dll,主要代碼是:
_declspec(dllexport) int add(int x, int y)
{
return x + y;
}
2.在DLLTest工程中添加DllTest.cpp文件.
首先使用LoadLibrary("add.dll")加載add.dll文件:
HMODULE hmod = LoadLibrary("add.dll");
然后定義一個(gè)函數(shù)指針的類型:
typedef int (*AddAddr)(int x, int y);
注意,這里的參數(shù)與返回類型務(wù)必與add.dll文件中函數(shù)add的聲明一樣。
接著:
AddAddr Add = (AddAddr)GetProcAddress(hmod, "add");
如果Add值為空,則獲取函數(shù)的地址失敗!
if(!Add)
{
printf("獲取函數(shù)地址失?。?);
return;
}
最后,可以測試一下:
printf("test add(): 1+2=%d", add(1,2));
運(yùn)行結(jié)果一看,會出現(xiàn)“獲取函數(shù)地址失敗!”。為什么會這樣?
打開命令行,用cd命令到add.dll工程目錄的debug目錄下,然后使用命令:
dumpbin -exports add.dll
則會看到add.dll文件中的add函數(shù)的名稱為“http://huangdekai1.blog.163.com/blog/static/30571416201111319123199/mailto:“?add@@YAHHH@Z”,而不是函數(shù)名add,這是C++編譯器的命名改編機(jī)制。 修改原來的代碼:
AddAddr Add = (AddAddr)GetProcAddress(hmod, "http://huangdekai1.blog.163.com/blog/static/30571416201111319123199/mailto:?add@@YAHHH@Z");
這時(shí)運(yùn)行就成功了。但如果按這樣去動態(tài)加載DLL,那每次獲取函數(shù)地址都要使用dumpbin命令去獲取,則會很麻煩。
那怎樣可以直接使用add而不是 http://huangdekai1.blog.163.com/blog/static/30571416201111319123199/mailto:?add@@YAHHH@Z這個(gè)長長的字符串呢,修改add.dll的add函數(shù),在函數(shù)前加上extern "C",再編譯add.dll文件所在的工程,復(fù)制新生成的add.dll覆蓋DLLTest工程目錄下的add.dll,原來的代碼獲取函數(shù)地址時(shí)使用add,結(jié)果運(yùn)行就成功了。
而再使用dumpbin -exports add.dll命令,顯示add.dll的中的add函數(shù)的名稱變成了add.
|
|