1、电 子 科 技 大 学 实 验 报 告 学生姓名: 学 号: 指导教师: 实验地点:A2-412 实验时间:2012、01、04 一、实验室名称: Linux环境高级编程实验室 二、实验项目名称: 插件框架实验 三、实验学时: 4学时 四、实验目得: 学习与实践插件框架得开发。理解插件得工作原理,为进一步开发高可用,高复杂度得插件打下基础。 五、实验内容: 1、使用动态链接库实现打印功能: 开发一个程序,向屏幕打印“Hello World”;在不重新编译链接原程序得前提下,将打印得文
2、字改为“Hello China”。 2、使用动态链接库实现自定义打印功能: 同时要打印“Hello World”,打印“Hello China”,甚至同时打印未来才会增加得其她打印信息,打印信息得链接库放在一个固定目录中,遍历这个目录,获取所有动态链接库。 打印未来得这些信息,也不能重新编译链接原程序。 3、 1)通过命令行方式:、/a、out help,输出所有插件实现得功能ID,以及该功能ID对应得功能描述。 2)通过命令行方式:、/a、out FuncID,调用具体打印功能(每个插件导出GetID接口)。 4、将插件导出得Print、GetID、Help三个函数放在一个类中
3、主程序需要使用多个容器分别保存这些函数地址,让插件外部获取该类得对象。
综合练习:实现一个软件系统,该系统可对文件进行统计分析。究竟对文件进行什么样得统计分析,最终用户自己也不就是很清楚,目前只知道需要统计文件得行数。也就就是说,本软件系统将会随时面临,增加文件统计新功能得难题。请结合本实验内容,设计并实现这样一个面向文件统计功能得插件系统。(需要实现得插件包括:统计某个文件得行数,统计某个文件得字节数)
六、实验步骤:
程序1:
A. h:
extern "c" void f();
a2、cpp:
#include
4、g namespace std;
void f()
{
cout << "hello,China!" << endl;
}
A1、cpp:
#include
5、handle = dlopen("、/libtest、so", RTLD_LAZY); if(0 == handle) { ﻩcout << "dlopen error" << endl; ﻩ return 0; } typedef void (*Fun)(); Fun f1 = (Fun)dlsym(handle, "f"); if(0 == f1) { ﻩﻩcout << "f1 error" << endl; char *str = dlerror(); ﻩ cout << str << endl
6、 } (*f1)(); dlclose(handle); return 0; } 程序运行结果如图1所示: 图1:字符得变换 程序2: A1、cpp: #include<iostream> using namespace std; extern"C" void f() { ﻩcout << "Hello world" << endl; } A2、cpp: #include<iostream> using namespace std; extern "C" void f() { cout << "Hello,
7、china!" << endl;
}
A3、cpp:
#include<iostream>
using namespace std;
extern "C" void f()
{
ﻩcout << "Hello 333" << endl;
}
A4、cpp:
#include
8、dirent、h>
#include
#include
9、ﻩ{ ﻩﻩcontinue; } ﻩ sprintf(path,"/root/test/test4/plug2/plugin/%s", ptr->d_name); ﻩvoid *handle = dlopen(path, RTLD_LAZY); if(0 == handle) { ﻩcout << "dlopen error" << endl; ﻩﻩ return 0; } ﻩ typedef void (*Fun)(); Fun pf = (Fun)dlsym(handle, "f"); ﻩ if(
10、0 == pf) ﻩ { cout << "pf error" << endl; char *str = dlerror(); ﻩ ﻩcout << str << endl; ﻩ return 0; ﻩ }ﻩ ﻩ (*pf)(); ﻩﻩdlclose(handle); } ﻩclosedir(dir); } 程序运行结果如图2所示: 图2:插件得遍历 程序3: a1、cpp: #include <iostream> using namespace std; const int FUNC_ID = 1; exter
11、n "C" void f() { cout << "Hello World!" << endl; } extern "C" void Help() { cout << "Function ID " << FUNC_ID << " : This function prints Hello World、" << endl; } a2、cpp: #include <iostream> using namespace std; const int FUNC_ID = 2; extern "C" void f() { cout << "Hello Ch
12、ina!" << endl;
}
extern "C" void Help()
{
cout << "Function ID " << FUNC_ID << " This function prints hello china、" << endl;
}
CPluginEnumerator、cpp
#include "CPluginEnumerator、h"
#include
13、nEnumerator()
{
}
CPluginEnumerator::~CPluginEnumerator()
{
}
bool CPluginEnumerator::GetPluginNames(vector
14、ptr == 0)
ﻩ break;
if((strcmp(ptr->d_name, "、") == 0)||(strcmp(ptr->d_name, "、、") == 0))
ﻩ continue;
ﻩchar path[260];
ﻩﻩsprintf(path, "/root/test/test4/plug3/plugin/%s", ptr->d_name);
vstrPluginNames、push_back(path);
}
closedir(dir);
ﻩreturn true;
}
Test、cpp:
#include 15、h>
#include <iostream>
#include "CPluginEnumerator、h"
#include 16、erator enumerator;
if(!enumerator、GetPluginNames(vstrPluginNames))
ﻩ{
ﻩ ﻩcout << "GetPluginNames error" << endl;
ﻩ return 0;
}
ﻩfor(int i = 0; i< vstrPluginNames、size(); i++)
{
ﻩﻩvoid *handle = dlopen(vstrPluginNames[i]、c_str(), RTLD_LAZY);
ﻩ ﻩif(handle == 0)
ﻩﻩ {
17、
ﻩﻩ cout << "dlopen error" << endl;
ﻩ return 0;
}
ﻩﻩﻩtypedef void (*FUNC_HELP)();
ﻩ FUNC_HELP dl_help = (FUNC_HELP)dlsym(handle, "Help");
ﻩ if(dl_help == 0)
ﻩﻩ{
ﻩﻩ ﻩcout << "dlsym error" << endl;
ﻩ return 0;
}
ﻩﻩ (dl_help)();
ﻩ dlclose(handle);
ﻩﻩ}
ﻩ}
ﻩelse if(strc 18、mp(argv[1], "1") == 0)
ﻩ{
sprintf(path, "/root/test/test4/plug3/plugin/%s", "a1、so");
ﻩvoid *handle = dlopen(path, RTLD_LAZY);
ﻩ if(handle == 0)
ﻩ{
ﻩﻩ cout << "dlopen error" << endl;
ﻩ return 0;
}
typedef void (*FUNC_PRINT)();
ﻩﻩFUNC_PRINT dl_print = (FUNC_PRINT)dlsym(handle, "f") 19、
ﻩ if(dl_print == 0)
ﻩﻩ{
ﻩﻩcout << "dlsym error" << endl;
return 0;
ﻩﻩ}
ﻩ(dl_print)();
ﻩ dlclose(handle);
ﻩ}
else if(strcmp(argv[1], "2") == 0)// 得到第二个func得参数
ﻩ{
ﻩ sprintf(path, "/root/test/test4/plug3/plugin/%s", "a2、so");
ﻩvoid *handle = dlopen(path, RTLD_LAZY);
if(handle == 20、 0)
ﻩ {
ﻩ cout << "dlopen error" << endl;
return 0;
ﻩ}
typedef void (*FUNC_PRINT)();
ﻩFUNC_PRINT dl_print = (FUNC_PRINT)dlsym(handle, "f");
if(dl_print == 0)
ﻩ{
ﻩcout << "dlsym error" << endl;
return 0;
}
ﻩ(dl_print)();
ﻩﻩdlclose(handle);
}
ﻩreturn 0;
}
程序运行结果如图3 21、所示:
图3:插件输出
程序4:
CPluginEnumerator、h:
#ifndef CPLUGINENUMERATOR_H
#define CPLUGINENUMERATOR_H
#include 22、vstrPluginNames);
};
#endif
CPluginEnumerator、cpp:
#include "CPluginEnumerator、h"
#include 23、 DIR *dir = opendir("、/plugin");
if(dir == 0)
return false;
for(;;)
{
ﻩstruct dirent *pentry = readdir(dir);
ﻩif(pentry == 0)
break;
if(strcmp(pentry->d_name, "、") == 0)
continue;
ﻩif(strcmp(pentry->d_name, "、、") == 0)
ﻩ continue;
ﻩstring str = "、/plugin/";
24、str += pentry->d_name;
ﻩvstrPluginNames、push_back(str);
}
closedir(dir);
return true;
}
CPluginController、h
#ifndef CPLUGINCONTROLLER_H
#define CPLUGINCONTROLLER_H
#include <vector>
class IPrintPlugin;
class CPluginController
{
public:
ﻩCPluginController(void);
virtual ~C 25、PluginController(void);
bool InitializeController(void);
bool UninitializeController(void);
ﻩbool ProcessHelp(void);
bool ProcessRequest(int FunctionID);
private:
std::vector<void *> m_vhForPlugin;
ﻩstd::vector 26、inController、h"
#include "CPluginEnumerator、h"
#include "IPrintPlugin、h"
#include "dlfcn、h"
CPluginController::CPluginController(void)
{
}
CPluginController::~CPluginController(void)
{
}
bool CPluginController::InitializeController(void)
{
ﻩstd::vector 27、uginEnumerator enumerator;
if(!enumerator、GetPluginNames(vstrPluginNames))
ﻩreturn false;
ﻩfor(unsigned int i=0 ; i 28、ginNames[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);
29、 ﻩﻩﻩ}
ﻩﻩ}
}
}
ﻩreturn true;
}
bool CPluginController::ProcessRequest(int FunctionID)
{
ﻩfor(unsigned int i = 0; i < m_vpPlugin、size(); i++)
ﻩ{
ﻩ if(m_vpPlugin[i]->GetID() == FunctionID)
{
ﻩ m_vpPlugin[i]->Print();
ﻩ ﻩbreak;
ﻩﻩ}
}
ﻩreturn true;
}
bool CPluginController::Proc 30、essHelp(void)
{
std::vector 31、 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)
ﻩﻩ ﻩ{
ﻩ ﻩpPlug 32、in->Help();
ﻩﻩ }
ﻩ ﻩ}
ﻩﻩﻩdlclose(hinstLib);
ﻩﻩ}
}
ﻩreturn true;
}
bool CPluginController::UninitializeController()
{
ﻩfor(unsigned int i = 0; i < m_vhForPlugin、size(); i++)
{
ﻩdlclose(m_vhForPlugin[i]);
}
return true;
}
IPrintPlugin、h
#pragma once
class IPrintPlugin
{
publi 33、c:
ﻩIPrintPlugin();
ﻩvirtual ~IPrintPlugin();
ﻩvirtual void Help() = 0;
ﻩvirtual void Print() = 0;
ﻩvirtual int GetID() = 0;
};
IPrintPlugin、cpp
#include "IPrintPlugin、h"
IPrintPlugin::IPrintPlugin()
{
}
IPrintPlugin::~IPrintPlugin()
{
}
Function、cpp
#include 34、rintPlugin、h"
using namespace std;
const int FUNC_ID = 1;
class CPrintPlugin : public IPrintPlugin
{
public:
CPrintPlugin()
ﻩ{
ﻩ}
virtual ~CPrintPlugin()
{
ﻩ}
virtual void Print()
ﻩ{
ﻩ cout << "Hello World!" << endl;
ﻩ}
ﻩvirtual void Help()
{
ﻩcout << "Function ID " << FUNC_I 35、D << " : This function will print hello world、" << endl;
}
ﻩvirtual int GetID(void)
ﻩ{
return FUNC_ID;
ﻩ}
};
extern "C" void CreateObj(IPrintPlugin **ppPlugin)
{
ﻩstatic CPrintPlugin plugin;
ﻩ*ppPlugin = &plugin;
}
function1、cpp
#include 36、amespace std;
const int FUNC_ID = 2;
class CPrintPlugin : public IPrintPlugin
{
public:
CPrintPlugin()
ﻩ{
ﻩ}
virtual ~CPrintPlugin()
{
ﻩ}
virtual void Print()
{
ﻩﻩcout << "Hello China!" << endl;
}
virtual void Help()
{
ﻩ cout << "Function ID " << FUNC_ID << " : This function 37、 will print hello china、" << endl;
}
ﻩvirtual int GetID(void)
{
return FUNC_ID;
}
};
extern "C" void CreateObj(IPrintPlugin **ppPlugin)
{
ﻩstatic CPrintPlugin plugin;
ﻩ*ppPlugin = &plugin;
}
Main、cpp
#include
#include "CPluginController、h"
#include <string、h>
#include 38、 <stdlib、h>
using namespace std;
int main(int argc, char **argv)
{
if(argc != 2)
ﻩ{
ﻩ cout << "Parameters error" << endl;
return 0;
ﻩ}
ﻩif(strcmp(argv[1], "help") == 0)
ﻩ{
ﻩﻩCPluginController pc;
pc、ProcessHelp();
ﻩreturn 0;
}
ﻩint FunctionID = atoi(argv[1]);
ﻩCPluginControlle 39、r pc;
pc、InitializeController();
ﻩpc、ProcessRequest(FunctionID);
pc、UninitializeController();
return 0;
}
程序运行结果如图4所示:
图4:插件获取类对象
综合练习:
CPluginController、cpp
#include "CPluginController、h"
#include "CPluginEnumerator、h"
#include "IPrintPlugin、h"
#include "dlfcn、h"
#include 40、h>
CPluginController::CPluginController(void)
{
}
CPluginController::~CPluginController(void)
{
}
bool CPluginController::InitializeController(void)
{
ﻩstd::vector 41、e;
for(unsigned int i=0 ; i 42、k(hinstLib);
ﻩﻩ CreateProc = (PLUGIN_CREATE)dlsym(hinstLib, "CreateObj");
if(NULL != CreateProc)
{
ﻩ ﻩﻩ(CreateProc)(&pPlugin);
ﻩ ﻩif(pPlugin != NULL)
ﻩﻩﻩ{
ﻩ ﻩﻩﻩm_vpPlugin、push_back(pPlugin);
ﻩ }
}
}
}
ﻩreturn true;
}
bool CPluginController::ProcessRequest(int Function 43、ID)
{
for(unsigned int i = 0; i < m_vpPlugin、size(); i++)
{
ﻩif(m_vpPlugin[i]->GetID() == FunctionID)
ﻩ {
ﻩ m_vpPlugin[i]->Print();
ﻩbreak;
}
ﻩ}
return true;
}
bool CPluginController::ProcessHelp(void)
{
ﻩstd::vector<std::string> vstrPluginNames;
ﻩCPluginEnumerator enumerator 44、
ﻩif(!enumerator、GetPluginNames(vstrPluginNames))
ﻩﻩreturn false;
for(unsigned int i=0 ; i<vstrPluginNames、size(); i++)
{
ﻩtypedef int (*PLUGIN_CREATE)(IPrintPlugin**);
PLUGIN_CREATE CreateProc;
ﻩIPrintPlugin *pPlugin = NULL;
ﻩﻩvoid* hinstLib = dlopen(vstrPluginNames[i]、c_str(), RTLD 45、LAZY);
ﻩif(hinstLib != NULL)
ﻩﻩ{
ﻩCreateProc = (PLUGIN_CREATE)dlsym(hinstLib, "CreateObj");
ﻩ if(NULL != CreateProc)
ﻩ ﻩ{
ﻩ (CreateProc)(&pPlugin);
ﻩﻩ if(pPlugin != NULL)
ﻩﻩﻩﻩ{
ﻩ pPlugin->Help();
ﻩ ﻩﻩ}
ﻩ }
ﻩﻩﻩdlclose(hinstLib);
ﻩﻩ}
ﻩ}
return true;
}
bool CPluginCon 46、troller::IfProcess(char *Function)//判断插件就是否存在
{
unsigned int i;
ﻩfor(i = 0; i < m_vpPlugin、size(); i++)
ﻩ{
if(strcmp(Function, m_vpPlugin[i]->GetName()) == 0)
ﻩﻩ{
ﻩﻩﻩbreak;
ﻩﻩ}
ﻩ};
ﻩif(i < m_vpPlugin、size())//插件存在
{
return true;
ﻩ}
ﻩelse
ﻩ{
ﻩreturn false;
}
}
bool CPluginC 47、ontroller::ProcessFunction(char *Function,char*Document)//执行插件功能
{
ﻩfor(unsigned int i = 0; i < m_vpPlugin、size(); i++)
{
ﻩ if(strcmp(Function, m_vpPlugin[i]->GetName()) == 0)
ﻩ{
ﻩﻩm_vpPlugin[i]->Fun(Document);//插件功能
ﻩﻩﻩbreak;
ﻩ}
}
return true;
}
bool CPluginController::Uninitializ 48、eController()
{
ﻩfor(unsigned int i = 0; i < m_vhForPlugin、size(); i++)
ﻩ{
dlclose(m_vhForPlugin[i]);
ﻩ}
ﻩreturn true;
}
CPluginController、h
#ifndef CPLUGINCONTROLLER_H
#define CPLUGINCONTROLLER_H
#include <vector>
class IPrintPlugin;
class CPluginController
{
public:
CPluginContr 49、oller(void);
virtual ~CPluginController(void);
bool InitializeController(void);
bool UninitializeController(void);
bool ProcessHelp(void);
ﻩbool ProcessRequest(int FunctionID);
bool IfProcess(char *Function);
ﻩbool ProcessFunction(char *Function,char *Document);
private:
std::vector<v 50、oid *> m_vhForPlugin;
ﻩstd::vector<IPrintPlugin*> m_vpPlugin;
};
#endif
CPluginEnumerator、h
#ifndef CPLUGINENUMERATOR_H
#define CPLUGINENUMERATOR_H
#include






