如何正确创建DLL和使用DLL
如何正確創(chuàng)建DLL和使用DLL
本文將通過(guò)一個(gè)簡(jiǎn)單的實(shí)例來(lái)說(shuō)明,如何正確的導(dǎo)出DLL中的類、對(duì)象、函數(shù),并如何通過(guò)靜態(tài)加載或動(dòng)態(tài)加載的方式來(lái)使用DLL。
一、DLL中導(dǎo)出類、函數(shù)、對(duì)象
1. 創(chuàng)建一個(gè)空的Win32 Dynamic-Link Library項(xiàng)目Test
2. 在項(xiàng)目中添加一個(gè)Test.h頭文件,該文件的內(nèi)容如下:
//導(dǎo)出類class?__declspec(dllexport)?CTest
{
...
};
//導(dǎo)出函數(shù)
__declspec(dllexport)?void?FuncTest();
//導(dǎo)出對(duì)象
extern?__declspec(dllexport)?CTest? ObjTest;
這段代碼中通過(guò)__declspec(dllexport)導(dǎo)出了類CTest、函數(shù)FuncTest和對(duì)象ObjTest。在.cpp文件中實(shí)現(xiàn)上面的聲明與類的定義后,經(jīng)編譯就可以生成一個(gè).dll和.lib文件了。
二、靜態(tài)加載DLL
1. 新建一個(gè)Win32 項(xiàng)目。
2. 將上面編譯生成的.lib文件復(fù)制到,該項(xiàng)目下。
3. 在項(xiàng)目中添加一個(gè)Test.h(通過(guò)該文件實(shí)現(xiàn)對(duì)DLL的靜態(tài)加載),該.h文件的內(nèi)容主要是從DLL的.h文件中復(fù)制過(guò)來(lái)。具體內(nèi)容如下:
#pragma?comment(lib,?"test.lib")//導(dǎo)入類
class?__declspec(dllimport)?CTest
...{
...
};
//導(dǎo)入函數(shù)
__declspec(dllimport)?void?FuncTest();
//導(dǎo)入對(duì)象
extern?__declspec(dllimport)?CTest??ObjTest;
這個(gè).h文件與dll的.h的不同就是,在開頭加了#pragma?comment(lib,?"test.lib"),以及類、函數(shù)、對(duì)象前面的__declspec(dllexport)變成了__declspec(dllimport)?。通過(guò)這些修改就可以告訴編譯器,這個(gè).h文件中定義的類、聲明的函數(shù)和對(duì)象?都是從test.dll中導(dǎo)入的。在項(xiàng)目中完成對(duì)這些類、函數(shù)、對(duì)象的調(diào)用代碼后,就可以將其編譯成可執(zhí)行文件。將生成的可執(zhí)行為文件、以及上面生成的.dll文件復(fù)制到同一個(gè)文件夾中就可以正常運(yùn)行這個(gè)可執(zhí)行文件。
三、動(dòng)態(tài)加載DLL
如果上面的DLL需要被動(dòng)態(tài)調(diào)用,這需在DLL的代碼中添加一個(gè) .def文件,在該文件中指出哪些被導(dǎo)出的函數(shù)和對(duì)象是可以動(dòng)態(tài)調(diào)用的。根據(jù)上面的例子.def文件的內(nèi)容如下:
LIBRARY????TestImpEXPORTS
????ObjTest ??????? FuncTest
在完成.def文件后,重新編譯dll。重新編譯dll后就可以對(duì)該Dll進(jìn)行動(dòng)態(tài)調(diào)用了,調(diào)用過(guò)程的代碼如下:
typedef?void?(*HFUNC)()HINSTANCE?hDLL?=?LoadLibrary("Test.dll");?????????????//加載DLL
if(hDLL)
{
?????????? HFUNC?hFun?=?(HFUNC)GetProcAddress(hDLL,?"FuncTest");???????//獲得Dll中FuncTest函數(shù)的指針。
?????????? if?(hFun)
???????????????? hFun();????//執(zhí)行函數(shù)FuncTest
??????????? else
????????????????? ?...????????????//沒(méi)有找到函數(shù)FuncTest
}
else
{
//加載失敗
}
?上面的代碼實(shí)現(xiàn)的對(duì)DLL中函數(shù)的動(dòng)態(tài)調(diào)用,在代碼中通過(guò)LoadLibrary將DLL加載到內(nèi)存中,然后GetProcAddress獲得指定函數(shù)所在的內(nèi)存地址(即該函數(shù)的函數(shù)指針),獲得指向這個(gè)函數(shù)的指針后就可以對(duì)它進(jìn)行調(diào)用了。
對(duì)于DLL中對(duì)象的動(dòng)態(tài)調(diào)用過(guò)程基本上是一樣的,先將DLL加載到內(nèi)存,然后通過(guò)GetProcAddress獲得對(duì)象所在的地址。
?從上面可以看出,DLL的動(dòng)態(tài)調(diào)用過(guò)程就是將DLL加載到內(nèi)存,然后通過(guò)GetProcAddress獲得DLL中指定對(duì)象或函數(shù)在該內(nèi)存中的地 址,通過(guò)該地址就可以對(duì)函數(shù)或?qū)ο筮M(jìn)行調(diào)用。由于在C++中沒(méi)有類的對(duì)象,也沒(méi)有類指針一說(shuō),所以是無(wú)法動(dòng)態(tài)使用DLL中的類的(如果誰(shuí)知道如何使用可以 告訴我)。
轉(zhuǎn)載于:https://www.cnblogs.com/fence/archive/2010/05/27/1745019.html
總結(jié)
以上是生活随笔為你收集整理的如何正确创建DLL和使用DLL的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問(wèn)題。
- 上一篇: 数据库完整性约束1
- 下一篇: 【分享】LazyLoad延迟加载(按需加