Linux插件框架实验报告.docx
《Linux插件框架实验报告.docx》由会员分享,可在线阅读,更多相关《Linux插件框架实验报告.docx(38页珍藏版)》请在冰豆网上搜索。
![Linux插件框架实验报告.docx](https://file1.bdocx.com/fileroot1/2023-2/10/db8080af-1d31-4058-9bad-f66207f99ddf/db8080af-1d31-4058-9bad-f66207f99ddf1.gif)
Linux插件框架实验报告
电子科技大学
实验报告
学生姓名:
学号:
指导教师:
实验地点:
A2-412实验时间:
2012.01.04
一、实验室名称:
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"<}
CPluginEnumerator.cpp
#include"CPluginEnumerator.h"
#include
#include
#include
#include
CPluginEnumerator:
:
CPluginEnumerator()
{
}
CPluginEnumerator:
:
~CPluginEnumerator()
{
}
boolCPluginEnumerator:
:
GetPluginNames(vector&vstrPluginNames)
{
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)
{
vectorvstrPluginNames;
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:
CPluginEnumerator.h:
#ifndefCPLUGINENUMERATOR_H
#defineCPLUGINENUMERATOR_H
#include
#include
usingnamespacestd;
classCPluginEnumerator
{
public:
CPluginEnumerator();
virtual~CPluginEnumerator();
boolGetPluginNames(vector&vstrPluginNames);
};
#endif
CPluginEnumerator.cpp:
#include"CPluginEnumerator.h"
#include
#include
CPluginEnumerator:
:
CPluginEnumerator()
{
}
CPluginEnumerator:
:
~CPluginEnumerator()
{
}
boolCPluginEnumerator:
:
GetPluginNames(vector&vstrPluginNames)
{
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;
}
CPluginController.h
#ifndefCPLUGINCONTROLLER_H
#defineCPLUGINCONTROLLER_H
#include
classIPrintPlugin;
classCPluginController
{
public:
CPluginController(void);
virtual~CPluginController(void);
boolInitializeController(void);
boolUninitializeController(void);
boolProcessHelp(void);
boolProcessRequest(intFunctionID);
private:
std:
:
vectorm_vhForPlugin;
std:
:
vectorm_vpPlugin;
};
#endif
CPluginController.cpp
#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;
}
IPrintPlugin.h
#pragmaonce
classIPrintPlugin
{
public:
IPrintPlugin();
virtual~IPrintPlugin();
virtualvoidHelp()=0;
virtualvoidPrint()=0;
virtualintGetID()=0;
};
IPrintPlugin.cpp
#include"IPrintPlugin.h"
IPrintPlugin:
:
IPrintPlugin()
{
}
IPrintPlugin:
:
~IPrintPlugin()
{
}
Function.cpp
#include
#include"IPrintPlugin.h"
usingnamespacestd;
constintFUNC_ID=1;
classCPrintPlugin:
publicIPrintPlugin
{
public:
CPrintPlugin()
{
}
virtual~CPrintPlugin()
{
}
virtualvoidPrint()
{
cout<<"HelloWorld!
"<}
virtualvoidHelp()
{
cout<<"FunctionID"<Thisfunction