剖析插件技術
作者:太子
mailto: tablejiang@21cn.com
轉載請保證文檔的完整性。
很多人對插件技術很感興趣,這兩天我對播放器的插件技術的原理做了些研究,現在就把 一些心得寫出來。
插件原理就是通過統一的程序接口來調用不同的模塊,以實現不同功能的調用。用來擴充 主程序的功能。
現在我們來談談它的實現。
插件技術的實現,一般都是先定義好一個接口結構。這個結構包含了主程序要引用的接 口函數的指針。當然,這些接口函數的格式必須是事先定義好了的。
而在插件Dll中一般只有一個導出函數,利用這個導出函數,我們可以得到接口結構的指針。
這樣主程序就可以通過指針來使用插件模塊中的功能了。
舉個例子:
我們先定義好包含接口函數的結構:
typedef struct PlugInModule{ DWORD Ver ; //版本 char *Author ; //作者說明 char *Description; //模塊說明 BYTE *InputPointer; //輸入數據 [in/out] DWORD dwSize ; //輸入數據的大小 [in] HWND hParentWnd ; //父窗口 [in] HINSTANCE hDllInst ; //Dll句柄 [in] void (*PlugIn_Config)( struct PlugInModule * pModule ) ; //設置函數 void (*PlugIn_Init)( struct PlugInModule * pModule ) ; //初始化函數 void (*PlugIn_Quit)( struct PlugInModule * pModule ) ; //退出函數 void (*PlugIn_Run )( struct PlugInModule * pModule ) ; //執行函數 } PlugInModule ;
還有申明Dll的導出函數:
typedef PlugInModule* (*GETPLUGINMODULE)();
這樣,我們就定義好了一個插件的接口。
在插件Dll中,可以這樣實現。
申明和定義接口函數。 //函數定義 void JhmDll_Config( struct PlugInModule * pModule ) ; //設置函數 void JhmDll_Init( struct PlugInModule * pModule ) ; //初始化函數 void JhmDll_Quit( struct PlugInModule * pModule ) ; //退出函數 void JhmDll_Run( struct PlugInModule * pModule ) ; //執行函數
//模塊函數實現 void JhmDll_Config( struct PlugInModule * pModule ) { char szDisplay[260] ; sprintf( szDisplay , "%s , config 模塊" , pModule->Description ) ; MessageBox( NULL , "config" , pModule->Author , MB_OK ) ; }
void JhmDll_Init( struct PlugInModule * pModule ) { char szDisplay[260] ; sprintf( szDisplay , "%s , Init 模塊" , pModule->Description ) ; MessageBox( NULL , "Init" , pModule->Author , MB_OK ) ; }
void JhmDll_Quit( struct PlugInModule * pModule ) { char szDisplay[260] ; sprintf( szDisplay , "%s , Quit 模塊" , pModule->Description ) ; MessageBox( NULL , "Quit" , pModule->Author , MB_OK ) ; }
void JhmDll_Run( struct PlugInModule * pModule ) { char szDisplay[260] ; sprintf( szDisplay , "%s , Run 模塊" , pModule->Description ) ; MessageBox( NULL , "Run" , pModule->Author , MB_OK ) ; }
這樣,我們就定義好了接口函數。 當然,我們必須把它們加入到接口結構中去。
這樣,再定義一個接口結構,并同時初始化: //初始化接口 PlugInModule module = { 0x0100 , "Table.JHM.太子" , "示范插件技術1--空模塊" , NULL , 0 , NULL , NULL , JhmDll_Config , JhmDll_Init , JhmDll_Quit , JhmDll_Run , };
然后再定義Dll的導出函數 //插件的接口 #ifdef __cplusplus extern "C" { #endif
__declspec( dllexport ) PlugInModule *GetPlugInModuleFunction() { return &module; }
#ifdef __cplusplus } #endif
這樣,一個插件dll的接口功能就完成了,當然,你需要在接口函數中添加你的插件功能代碼。
這樣主程序再通過動態加載Dll,映射導出函數地址, 就可以通過導出函數 GetPlugInModuleFunction()得到一個PlugInModule結構的指針。而PlugInMoudle包含插件功能 的功能函數地址,這樣就可以引用 void JhmDll_Config( struct PlugInModule * pModule ) ; //設置函數 void JhmDll_Init( struct PlugInModule * pModule ) ; //初始化函數 void JhmDll_Quit( struct PlugInModule * pModule ) ; //退出函數 void JhmDll_Run( struct PlugInModule * pModule ) ; //執行函數 這些插件函數的功能了。
這只是個人想法,如果有不同意見的可以 email 。歡迎討論。
如果需要更詳細的內容,大家可以到http://wolfftp.51.net 或 http://mywolfsoft.51.net 去 下載示范源代碼。 |