资源描述
电 子 科 技 大 学
实 验 报 告
学生姓名: 学 号: 指导教师:
实验地点:A2-412 实验时间:2012、01、04
一、实验室名称:
Linux环境高级编程实验室
二、实验项目名称:
插件框架实验
三、实验学时:
4学时
四、实验目得:
学习与实践插件框架得开发。理解插件得工作原理,为进一步开发高可用,高复杂度得插件打下基础。
五、实验内容:
1、使用动态链接库实现打印功能:
开发一个程序,向屏幕打印“Hello World”;在不重新编译链接原程序得前提下,将打印得文字改为“Hello China”。
2、使用动态链接库实现自定义打印功能:
同时要打印“Hello World”,打印“Hello China”,甚至同时打印未来才会增加得其她打印信息,打印信息得链接库放在一个固定目录中,遍历这个目录,获取所有动态链接库。
打印未来得这些信息,也不能重新编译链接原程序。
3、
1)通过命令行方式:、/a、out help,输出所有插件实现得功能ID,以及该功能ID对应得功能描述。
2)通过命令行方式:、/a、out FuncID,调用具体打印功能(每个插件导出GetID接口)。
4、将插件导出得Print、GetID、Help三个函数放在一个类中,主程序需要使用多个容器分别保存这些函数地址,让插件外部获取该类得对象。
综合练习:实现一个软件系统,该系统可对文件进行统计分析。究竟对文件进行什么样得统计分析,最终用户自己也不就是很清楚,目前只知道需要统计文件得行数。也就就是说,本软件系统将会随时面临,增加文件统计新功能得难题。请结合本实验内容,设计并实现这样一个面向文件统计功能得插件系统。(需要实现得插件包括:统计某个文件得行数,统计某个文件得字节数)
六、实验步骤:
程序1:
A. h:
extern "c" void f();
a2、cpp:
#include<iostream>
#include"a、h"
using namespace std;
void f()
{
cout << "hello,China!" << endl;
}
A1、cpp:
#include<iostream>
#include"a、h"
using namespace std;
void f()
{
cout << "Hello,Word" << endl;
}
Main、cpp:
#include"a、h"
#include<dlfcn、h>
#include<iostream>
using namespace std;
int main()
{
void *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;
}
(*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,china!" << endl;
}
A3、cpp:
#include<iostream>
using namespace std;
extern "C" void f()
{
ﻩcout << "Hello 333" << endl;
}
A4、cpp:
#include<iostream>
using namespace std;
extern "C" void f()
{
ﻩcout << "Hello 4444" << endl;
}
Test2、cpp:
#include<dlfcn、h>
#include<iostream>
#include<dirent、h>
#include<stdio、h>
#include<string、h>
using namespace std;
int main()
{
ﻩchar path[260];
ﻩDIR *dir;
ﻩstruct dirent *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 << "dlopen error" << endl;
ﻩﻩ return 0;
}
ﻩ typedef void (*Fun)();
Fun pf = (Fun)dlsym(handle, "f");
ﻩ if(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;
extern "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 China!" << endl;
}
extern "C" void Help()
{
cout << "Function ID " << FUNC_ID << " This function prints hello china、" << endl;
}
CPluginEnumerator、cpp
#include "CPluginEnumerator、h"
#include <dirent、h>
#include <string、h>
#include <iostream>
#include <stdio、h>
CPluginEnumerator::CPluginEnumerator()
{
}
CPluginEnumerator::~CPluginEnumerator()
{
}
bool CPluginEnumerator::GetPluginNames(vector<string>& vstrPluginNames)
{
DIR *dir = opendir("/root/test/test4/plug3/plugin");
if(dir == 0)
ﻩﻩreturn false;
for(;;)
{
struct dirent *ptr = readdir(dir);
ﻩif(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 <dlfcn、h>
#include <iostream>
#include "CPluginEnumerator、h"
#include <string、h>
#include <stdio、h>
using namespace std;
int main(int argc, char **argv)
{
ﻩchar path [260];
if(argc != 2)
ﻩreturn 0;
if(strcmp(argv[1], "help") == 0)
{
vector<string> vstrPluginNames;
CPluginEnumerator 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)
ﻩﻩ {
ﻩﻩ 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(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 << "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);
ﻩ}
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 == 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所示:
图3:插件输出
程序4:
CPluginEnumerator、h:
#ifndef CPLUGINENUMERATOR_H
#define CPLUGINENUMERATOR_H
#include <vector>
#include <string>
using namespace std;
class CPluginEnumerator
{
public:
CPluginEnumerator();
virtual ~CPluginEnumerator();
bool GetPluginNames(vector<string>& vstrPluginNames);
};
#endif
CPluginEnumerator、cpp:
#include "CPluginEnumerator、h"
#include <dirent、h>
#include <string、h>
CPluginEnumerator::CPluginEnumerator()
{
}
CPluginEnumerator::~CPluginEnumerator()
{
}
bool CPluginEnumerator::GetPluginNames(vector<string>& vstrPluginNames)
{
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/";
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 ~CPluginController(void);
bool InitializeController(void);
bool UninitializeController(void);
ﻩbool ProcessHelp(void);
bool ProcessRequest(int FunctionID);
private:
std::vector<void *> m_vhForPlugin;
ﻩstd::vector<IPrintPlugin*> m_vpPlugin;
};
#endif
CPluginController、cpp
#include "CPluginController、h"
#include "CPluginEnumerator、h"
#include "IPrintPlugin、h"
#include "dlfcn、h"
CPluginController::CPluginController(void)
{
}
CPluginController::~CPluginController(void)
{
}
bool CPluginController::InitializeController(void)
{
ﻩstd::vector<std::string> vstrPluginNames;
CPluginEnumerator enumerator;
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_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);
ﻩﻩﻩ}
ﻩﻩ}
}
}
ﻩ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::ProcessHelp(void)
{
std::vector<std::string> vstrPluginNames;
CPluginEnumerator enumerator;
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_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 CPluginController::UninitializeController()
{
ﻩfor(unsigned int i = 0; i < m_vhForPlugin、size(); i++)
{
ﻩdlclose(m_vhForPlugin[i]);
}
return true;
}
IPrintPlugin、h
#pragma once
class IPrintPlugin
{
public:
ﻩ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 <iostream>
#include "IPrintPlugin、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_ID << " : 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 <iostream>
#include "IPrintPlugin、h"
using namespace 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 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 <iostream>
#include "CPluginController、h"
#include <string、h>
#include <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]);
ﻩCPluginController 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 <string、h>
CPluginController::CPluginController(void)
{
}
CPluginController::~CPluginController(void)
{
}
bool CPluginController::InitializeController(void)
{
ﻩstd::vector<std::string> vstrPluginNames;
ﻩCPluginEnumerator enumerator;
ﻩ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_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);
ﻩ }
}
}
}
ﻩ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::ProcessHelp(void)
{
ﻩstd::vector<std::string> vstrPluginNames;
ﻩCPluginEnumerator enumerator;
ﻩ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_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 CPluginController::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 CPluginController::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::UninitializeController()
{
ﻩ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:
CPluginController(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<void *> m_vhForPlugin;
ﻩstd::vector<IPrintPlugin*> m_vpPlugin;
};
#endif
CPluginEnumerator、h
#ifndef CPLUGINENUMERATOR_H
#define CPLUGINENUMERATOR_H
#include <vector>
#include <string>
using namespace std;
class CPluginEnumerator
{
public:
CPluginEnumerator();
virtual ~CPluginEn
展开阅读全文