其實,插件不過就是調用dll中的函數(shù)而已,不過通過類似一個com中的接口,再通過接口查詢到相應的服務來處理。
復雜的插件,當然有考慮采用com方式的,不過作為編寫程序的原則是簡單,實效,通用。又何須采用太過專業(yè)的方法。
技術不過是手段,能在達到目的的最大化程度上實現(xiàn),就足矣。
下面的例子來自網(wǎng)上,作者不詳,稍微整編下。直接貼代碼在上面。源碼打包放在自己博客的文檔中。算是自己學習整理,
也感謝提供者。
源碼學習:http://www.shnenglu.com/Files/kenlistian/test_plus.rar
1.定義插件的接口結構
/*
定義一個plus 接口結構
*/
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ù)
void (*PlugIn_Init)( struct PlugInModule * pModule ); //初始化函數(shù)
void (*PlugIn_Quit)( struct PlugInModule * pModule ); //退出函數(shù)
void (*PlugIn_Run )( struct PlugInModule * pModule ); //執(zhí)行函數(shù)
} PlugInModule;
其中接口結構函數(shù),被規(guī)定了4個,也就是說這個接口函數(shù)定死了,如果以后應為功能增加等等,
則估計這個結構都要改寫。所以采用com方式接口方式則是一種好的選擇,而那種模式,每次還要注冊com,
則莫免麻煩和釘死在windows平臺上。
2.以上接口結構放置在頭文件中。作為主程序和dll共享的頭文件,其中,再在頭文件中具體聲明以上結構體中函數(shù)。
void plusDll_Config( struct PlugInModule * pModule); //設置函數(shù)
void PlusDll_Init( struct PlugInModule * pModule ); //初始化函數(shù)
void plusDll_Quit( struct PlugInModule * pModule ); //退出函數(shù)
void plusDll_Run( struct PlugInModule * pModule ); //執(zhí)行函數(shù)
3.在頭文件中聲明一個返回該結構的函數(shù)。其實就是一個回調函數(shù)。把該結構返回給主程序的一個export 函數(shù)。
typedef PlugInModule* (*GETPLUGINMODULE)(); //聲明接口函數(shù)地址
/**
導出函數(shù),主程序首先獲取該接口函數(shù),獲得 dll中的函數(shù)地址,調用
*/
DLL_001_API PlugInModule* GetPlugInModuleFunction(); //DLL_001_API ==> __declspec(dllexport)
4.在dll中定義該插件結構,把地址通過GetPlugInModuleFunction傳入到主程序。
5.分別實現(xiàn)dll中和主程序的定義部分。通過動態(tài)加載方式即可實現(xiàn)取出dll的結構體指針。
如下示:
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文件;