如何开发一个高效可用的多插件运行程序?插件接口是关键。
设计一个高效可用的插件接口,会让程序节省很多资源和时间。
设计插件接口是一件容易的事,但设计一个高效的插件就不是一件容易的事。现在学习一下本公司老大的设计插件的方式以及思路。
插件一般来说要么是动态库要么是静态库,那么多个同级插件可以使用统一接口来进行实现。打开动态库的方式一种是静态链接一种动态打开。
一般来说静态链接就是在编译的时候把所有的动态库用'-L'全部链接编译进去,这是一个死方法,意思说我只能加载一定的模块,想要再加那么就得从新编译一下程序。这种方式一般在代码动态开发中是不可取的(这种情况在动态库固定且很少的情况下使用)。
如果要开发可配置且能动态的加载程序所需要的插件,那么Windows就是用
HINSTANCE hDllInst = LoadLibrary("youApp.DLL");
MYFUNC youFuntionNameAlias = NULL; // youFuntionNameAlias 函数别名
youFuntionNameAlias = (MYFUNC)GetProcAddress(hDllInst,"youFuntionName");
方式在程序中打开就可以了。
Linux用
void *dlopen(const char * filename, int flag);//打开动态库
void *dlsym(void *handle, char*symbol);//获取功能函数
const char *dlerror();
int dlclose(void *handle);//关闭
在这里通过配置文件添加设置动态库,配置文件自己可以随意设计,然后用vector将配置文件中要加载的动态库名称记录下来,然后再循环读取加载插件模块。
公共接口设计示例:
#ifndef PLUGIN_H
#define PLUGIN_H
#if defined (WIN32) || defined(_WIN64)
#define PLUGIN_API extern "C" __declspec(dllexport)
#else
#define PLUGIN_API extern "C"
#endif
class plugin
{
public:
plugin(){};
~plugin(){};
virtual void init();//初始化功能
virtual void func1();//公共功能函数1
virtual void func2();//功能函数2
};
/*插件获取当前动态库对象,每个插件必须实现*/
PLUGIN_API plugin * create_instance();
#endif
/*
plugin * create_instance()
{
plugin * XXXpugin = new xxxclass();//new一个插件对象进行返回
return XXXpugin;
}
*/
根据接口我们就可以实现自己想要的插件了。
在程序中再将动态打开的插件用list进行关联存储(list<string ,plugin *> plugin_list)。后面如果你想使用某个插件的时候直接调用就ok了。