Linux插件框架实验报告.docx
- 文档编号:10439508
- 上传时间:2023-02-11
- 格式:DOCX
- 页数:20
- 大小:17.92KB
Linux插件框架实验报告.docx
《Linux插件框架实验报告.docx》由会员分享,可在线阅读,更多相关《Linux插件框架实验报告.docx(20页珍藏版)》请在冰豆网上搜索。
Linux插件框架实验报告
电子科技大学之欧侯瑞魂创作
时间:
二O二一年七月二十九日
实验报告
学生姓名:
学号:
指导教师:
实验地点:
A2-412
一、实验室名称:
Linux环境高级编程实验室
二、实验项目名称:
插件框架实验
三、实验学时:
4学时
四、实验目的:
学习和实践插件框架的开发。
理解插件的工作原理,为进一步开发高可用,高复杂度的插件打下基础。
五、实验内容:
1、使用动态链接库实现打印功能:
开发一个程序,向屏幕打印“HelloWorld”;在不重新编译链接原程序的前提下,将打印的文字改为“HelloChina”。
2、使用动态链接库实现自定义打印功能:
同时要打印“HelloWorld”,打印“HelloChina”,甚至同时打印未来才会增加的其他打印信息,打印信息的链接库放在一个固定目录中,遍历这个目录,获取所有动态链接库。
打印未来的这些信息,也不克不及重新编译链接原程序。
3、
1)通过命令行方式:
./a.outhelp,输出所有插件实现的功能ID,以及该功能ID对应的功能描述。
2)通过命令行方式:
./a.outFuncID,调用具体打印功能(每个插件导出GetID接口)。
4、将插件导出的Print、GetID、Help三个函数放在一个类中,主程序需要使用多个容器分别保管这些函数地址,让插件外部获取该类的对象。
综合练习:
实现一个软件系统,该系统可对文件进行统计分析。
究竟对文件进行什么样的统计分析,最终用户自己也不是很清楚,目前只知道需要统计文件的行数。
也就是说,本软件系统将会随时面临,增加文件统计新功能的难题。
请结合本实验内容,设计并实现这样一个面向文件统计功能的插件系统。
(需要实现的插件包含:
统计某个文件的行数,统计某个文件的字节数)
六、实验步调:
程序1:
A.h:
extern"c"voidf();
a2.cpp:
#include
#include"a.h"
usingnamespacestd;
voidf()
{
cout<<"hello,China!
"< } A1.cpp: #include #include"a.h" usingnamespacestd; voidf() { cout<<"Hello,Word"< } Main.cpp: #include"a.h" #include #include usingnamespacestd; intmain() { void*handle=dlopen("./libtest.so",RTLD_LAZY); if(0==handle) { cout<<"dlopenerror"< return0; } typedefvoid(*Fun)(); Funf1=(Fun)dlsym(handle,"f"); if(0==f1) { cout<<"f1error"< char*str=dlerror(); cout< } (*f1)(); dlclose(handle); return0; } 程序运行结果如图1所示: 图1: 字符的变换 程序2: A1.cpp: #include usingnamespacestd; extern"C"voidf() { cout<<"Helloworld"< } A2.cpp: #include usingnamespacestd; extern"C"voidf() { cout<<"Hello,china! "< } A3.cpp: #include usingnamespacestd; extern"C"voidf() { cout<<"Hello333"< } A4.cpp: #include usingnamespacestd; extern"C"voidf() { cout<<"Hello4444"< } Test2.cpp: #include #include #include #include #include usingnamespacestd; intmain() { charpath[260]; DIR*dir; structdirent*ptr; dir=opendir("/root/test/test4/plug2/plugin/"); while((ptr=readdir(dir))! =NULL) { if((strcmp(ptr->d_name,"..")==0)||(strcmp(ptr->d_name,".")==0)) { continue; } sprintf(path,"/root/test/test4/plug2/plugin/%s",ptr->d_name); void*handle=dlopen(path,RTLD_LAZY); if(0==handle) { cout<<"dlopenerror"< return0; } typedefvoid(*Fun)(); Funpf=(Fun)dlsym(handle,"f"); if(0==pf) { cout<<"pferror"< char*str=dlerror(); cout< return0; } (*pf)(); dlclose(handle); } closedir(dir); } 程序运行结果如图2所示: 图2: 插件的遍历 程序3: a1.cpp: #include usingnamespacestd; constintFUNC_ID=1; extern"C"voidf() { cout<<"HelloWorld! "< } extern"C"voidHelp() { cout<<"FunctionID"< ThisfunctionprintsHelloWorld."< } a2.cpp: #include usingnamespacestd; constintFUNC_ID=2; extern"C"voidf() { cout<<"HelloChina! "< } extern"C"voidHelp() { cout<<"FunctionID"< } #include"CPluginEnumerator.h" #include #include #include #include CPluginEnumerator: : CPluginEnumerator() { } CPluginEnumerator: : ~CPluginEnumerator() { } boolCPluginEnumerator: : GetPluginNames(vector { DIR*dir=opendir("/root/test/test4/plug3/plugin"); if(dir==0) returnfalse; for(;;) { structdirent*ptr=readdir(dir); if(ptr==0) break; if((strcmp(ptr->d_name,".")==0)||(strcmp(ptr->d_name,"..")==0)) continue; charpath[260]; sprintf(path,"/root/test/test4/plug3/plugin/%s",ptr->d_name); vstrPluginNames.push_back(path); } closedir(dir); returntrue; } Test.cpp: #include #include #include"CPluginEnumerator.h" #include #include usingnamespacestd; intmain(intargc,char**argv) { charpath[260]; if(argc! =2) return0; if(strcmp(argv[1],"help")==0) { vector CPluginEnumeratorenumerator; if(! enumerator.GetPluginNames(vstrPluginNames)) { cout<<"GetPluginNameserror"< return0; } for(inti=0;i { void*handle=dlopen(vstrPluginNames[i].c_str(),RTLD_LAZY); if(handle==0) { cout<<"dlopenerror"< return0; } typedefvoid(*FUNC_HELP)(); FUNC_HELPdl_help=(FUNC_HELP)dlsym(handle,"Help"); if(dl_help==0) { cout<<"dlsymerror"< return0; } (dl_help)(); dlclose(handle); } } elseif(strcmp(argv[1],"1")==0) { sprintf(path,"/root/test/test4/plug3/plugin/%s","a1.so"); void*handle=dlopen(path,RTLD_LAZY); if(handle==0) { cout<<"dlopenerror"< return0; } typedefvoid(*FUNC_PRINT)(); FUNC_PRINTdl_print=(FUNC_PRINT)dlsym(handle,"f"); if(dl_print==0) { cout<<"dlsymerror"< return0; } (dl_print)(); dlclose(handle); } elseif(strcmp(argv[1],"2")==0)//得到第二个func的参数 { sprintf(path,"/root/test/test4/plug3/plugin/%s","a2.so"); void*handle=dlopen(path,RTLD_LAZY); if(handle==0) { cout<<"dlopenerror"< return0; } typedefvoid(*FUNC_PRINT)(); FUNC_PRINTdl_print=(FUNC_PRINT)dlsym(handle,"f"); if(dl_print==0) { cout<<"dlsymerror"< return0; } (dl_print)(); dlclose(handle); } return0; } 程序运行结果如图3所示: 图3: 插件输出 程序4: : #ifndefCPLUGINENUMERATOR_H #defineCPLUGINENUMERATOR_H #include #include usingnamespacestd; classCPluginEnumerator { public: CPluginEnumerator(); virtual~CPluginEnumerator(); boolGetPluginNames(vector }; #endif : #include"CPluginEnumerator.h" #include #include CPluginEnumerator: : CPluginEnumerator() { } CPluginEnumerator: : ~CPluginEnumerator() { } boolCPluginEnumerator: : GetPluginNames(vector { DIR*dir=opendir("./plugin"); if(dir==0) returnfalse; for(;;) { structdirent*pentry=readdir(dir); if(pentry==0) break; if(strcmp(pentry->d_name,".")==0) continue; if(strcmp(pentry->d_name,"..")==0) continue; stringstr="./plugin/"; str+=pentry->d_name; vstrPluginNames.push_back(str); } closedir(dir); returntrue; } #ifndefCPLUGINCONTROLLER_H #defineCPLUGINCONTROLLER_H #include classIPrintPlugin; classCPluginController { public: CPluginController(void); virtual~CPluginController(void); boolInitializeController(void); boolUninitializeController(void); boolProcessHelp(void); boolProcessRequest(intFunctionID); private: std: : vector std: : vector }; #endif #include"CPluginController.h" #include"CPluginEnumerator.h" #include"IPrintPlugin.h" #include"dlfcn.h" CPluginController: : CPluginController(void) { } CPluginController: : ~CPluginController(void) { } boolCPluginController: : InitializeController(void) { std: : vector : string>vstrPluginNames; CPluginEnumeratorenumerator; if(! enumerator.GetPluginNames(vstrPluginNames)) returnfalse; for(unsignedinti=0;i { typedefint(*PLUGIN_CREATE)(IPrintPlugin**); PLUGIN_CREATECreateProc; IPrintPlugin*pPlugin=NULL; void*hinstLib=dlopen(vstrPluginNames[i].c_str(),RTLD_LAZY); if(hinstLib! =NULL) { m_vhForPlugin.push_back(hinstLib); CreateProc=(PLUGIN_CREATE)dlsym(hinstLib,"CreateObj"); if(NULL! =CreateProc) { (CreateProc)(&pPlugin); if(pPlugin! =NULL) { m_vpPlugin.push_back(pPlugin); } } } } returntrue; } boolCPluginController: : ProcessRequest(intFunctionID) { for(unsignedinti=0;i { if(m_vpPlugin[i]->GetID()==FunctionID) { m_vpPlugin[i]->Print(); break; } } returntrue; } boolCPluginController: : ProcessHelp(void) { std: : vector : string>vstrPluginNames; CPluginEnumeratorenumerator; if(! enumerator.GetPluginNames(vstrPluginNames)) returnfalse; for(unsignedinti=0;i { typedefint(*PLUGIN_CREATE)(IPrintPlugin**); PLUGIN_CREATECreateProc; IPrintPlugin*pPlugin=NULL; void*hinstLib=dlopen(vstrPluginNames[i].c_str(),RTLD_LAZY); if(hinstLib! =NULL) { CreateProc=(PLUGIN_CREATE)dlsym(hinstLib,"CreateObj"); if(NULL! =CreateProc) { (CreateProc)(&pPlugin); if(pPlugin! =NULL) { pPlugin->Help(); } } dlclose(hinstLib); } } returntrue; } boolCPluginController: : UninitializeController() { for(unsignedinti=0;i { dlclose(m_vhForPlugin[i]); } returntrue; } #pragmaonce classIPrintPlugin { public: IPrintPlugin(); virtual~IPrintPlugin(); virtualvoidHelp()=0; virtualvoidPrint()=0; virtualintGetID()=0; }; #include"IPrintPlugin.h" IPrintPlugin: : IPrintPlugin() { } IPrintPlugin: : ~IPrintPlugin() { } #include #include"IPrintPlugin.h" usingnamespacestd; constintFUNC_ID=1; classCPrintPlugin: publicIPrintPlugin { public: CPrintPlugin() { } virtual~CPrintPlugin() { } virtualvoidPrint() { cout<<"HelloWorld! "< } virtualvoidHelp() { cout<<"FunctionID"< Thisfunctionwillprinthelloworld."< } virtualintGetID(void) { returnFUNC_ID; } }; extern"C"voidCreateObj(IPrintPlugin**ppPlugin) { staticCPrintPluginplugin; *ppPlugin=&plugin; } #include #include"IPrintPlugin.h" usingnamespacestd; constintFUNC_ID=2; classCPrintPlugin: publicIPrintPlugin { public: CPrintPlugin() { } virtual~CPrintPlugin() { } virtualvoidPrint() 时间: 二O二一年七月二十九日
- 配套讲稿:
如PPT文件的首页显示word图标,表示该PPT已包含配套word讲稿。双击word图标可打开word文档。
- 特殊限制:
部分文档作品中含有的国旗、国徽等图片,仅作为作品整体效果示例展示,禁止商用。设计者仅对作品中独创性部分享有著作权。
- 关 键 词:
- Linux 插件 框架 实验 报告