其實(shí),插件不過就是調(diào)用dll中的函數(shù)而已,不過通過類似一個(gè)com中的接口,再通過接口查詢到相應(yīng)的服務(wù)來處理。
復(fù)雜的插件,當(dāng)然有考慮采用com方式的,不過作為編寫程序的原則是簡(jiǎn)單,實(shí)效,通用。又何須采用太過專業(yè)的方法。
技術(shù)不過是手段,能在達(dá)到目的的最大化程度上實(shí)現(xiàn),就足矣。
下面的例子來自網(wǎng)上,作者不詳,稍微整編下。直接貼代碼在上面。源碼打包放在自己博客的文檔中。算是自己學(xué)習(xí)整理,
也感謝提供者。
源碼學(xué)習(xí):http://www.shnenglu.com/Files/kenlistian/test_plus.rar
1.定義插件的接口結(jié)構(gòu)
/*
定義一個(gè)plus 接口結(jié)構(gòu)
*/
typedef struct PlugInModule{
DWORD Ver ; //版本
char *Author ; //作者說明
char *Description; //模塊說明
BYTE *InputPointer; //輸入數(shù)據(jù)
DWORD dwSize ; //輸入數(shù)據(jù)的大小
HWND hParentWnd ; //主程序的父窗口
HINSTANCE hDllInst ; //Dll句柄
void (*PlugIn_Config)( struct PlugInModule * pModule ); //設(shè)置函數(shù)
void (*PlugIn_Init)( struct PlugInModule * pModule ); //初始化函數(shù)
void (*PlugIn_Quit)( struct PlugInModule * pModule ); //退出函數(shù)
void (*PlugIn_Run )( struct PlugInModule * pModule ); //執(zhí)行函數(shù)
} PlugInModule;
其中接口結(jié)構(gòu)函數(shù),被規(guī)定了4個(gè),也就是說這個(gè)接口函數(shù)定死了,如果以后應(yīng)為功能增加等等,
則估計(jì)這個(gè)結(jié)構(gòu)都要改寫。所以采用com方式接口方式則是一種好的選擇,而那種模式,每次還要注冊(cè)com,
則莫免麻煩和釘死在windows平臺(tái)上。
2.以上接口結(jié)構(gòu)放置在頭文件中。作為主程序和dll共享的頭文件,其中,再在頭文件中具體聲明以上結(jié)構(gòu)體中函數(shù)。
void plusDll_Config( struct PlugInModule * pModule); //設(shè)置函數(shù)
void PlusDll_Init( struct PlugInModule * pModule ); //初始化函數(shù)
void plusDll_Quit( struct PlugInModule * pModule ); //退出函數(shù)
void plusDll_Run( struct PlugInModule * pModule ); //執(zhí)行函數(shù)
3.在頭文件中聲明一個(gè)返回該結(jié)構(gòu)的函數(shù)。其實(shí)就是一個(gè)回調(diào)函數(shù)。把該結(jié)構(gòu)返回給主程序的一個(gè)export 函數(shù)。
typedef PlugInModule* (*GETPLUGINMODULE)(); //聲明接口函數(shù)地址
/**
導(dǎo)出函數(shù),主程序首先獲取該接口函數(shù),獲得 dll中的函數(shù)地址,調(diào)用
*/
DLL_001_API PlugInModule* GetPlugInModuleFunction(); //DLL_001_API ==> __declspec(dllexport)
4.在dll中定義該插件結(jié)構(gòu),把地址通過GetPlugInModuleFunction傳入到主程序。
5.分別實(shí)現(xiàn)dll中和主程序的定義部分。通過動(dòng)態(tài)加載方式即可實(shí)現(xiàn)取出dll的結(jié)構(gòu)體指針。
如下示:
hDLL = LoadLibrary("dll_001\\debug\\dll_001.dll");
if (hDLL)
MessageBox(NULL,"plus_Dll load ok", "", MB_OK);
else
{
MessageBox(NULL, "not found plus_dll","",MB_OK);
return 0;
}
pFunction = (GETPLUGINMODULE)::GetProcAddress(hDLL,"GetPlugInModuleFunction");
if (pFunction != NULL)
{
dllplus_module = (*pFunction)();
dllplus_module->PlugIn_Init(dllplus_module);
dllplus_module->PlugIn_Run(dllplus_module);
dllplus_module->PlugIn_Quit(dllplus_module);
}
::FreeLibrary(hDLL);//卸載MyDll.dll文件;