首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >写一个插件系统?

写一个插件系统?
EN

Stack Overflow用户
提问于 2014-10-31 07:14:37
回答 1查看 1.4K关注 0票数 3

经过几个小时的研究,我什么也没发现,所以我向你们求助,希望能找到解决办法。我将用c++编写一个机器人,并希望在某个时候为它制作一个插件系统。现在我知道我可以为它编写一种脚本语言,但是,我知道只需要编写一个api并在运行时动态地拥有到它的程序链接就可以了。我的问题是,我如何获得动态链接(就像十六进制的插件)?是否有任何优雅的解决方案,或至少在典型的设计理论?

EN

回答 1

Stack Overflow用户

发布于 2014-10-31 10:39:33

在Linux系统上,您希望使用dlopen(3) & dlsym (或者一些封装这些函数的库,例如来自GTK、Qt波科等的滑翔 )。更准确地说,

构建一个位置独立码共享库作为插件:

代码语言:javascript
复制
 gcc -fPIC -Wall -c plugin1.c -o plugin1.pic.o
 gcc -fPIC -Wall -c plugin2.c -o plugin2.pic.o

注意,如果插件是用C++编写的,您将用g++编译它,您应该将插件函数声明为extern "C",以避免使用名称残缺

然后将您的插件链接为

代码语言:javascript
复制
 gcc -shared -Wall plugin1.pic.o plugin2.pic.o -o plugin.so

您可以添加动态库(例如,如果您的插件想要GNU,请在上面命令的末尾添加一个-lreadline )。

最后,在您的主程序中调用具有完整路径的dlopen

代码语言:javascript
复制
 void* dlh = dlopen("./plugin.so", RTLD_NOW);
 if (!dlh) { fprintf(stderr, "dlopen failed: %s\n", dlerror()); 
             exit(EXIT_FAILURE); };

( dlh通常是一个全局数据)

然后使用dlsym获取函数指针。因此,在程序和插件代码都包含的标题中声明它们的签名,如

代码语言:javascript
复制
 typedef int readerfun_t (FILE*);

声明一些(经常)全局函数指针

代码语言:javascript
复制
 readerfun_t* readplugfun;

并在插件句柄dlsym上使用dlh

代码语言:javascript
复制
 readplugfun = (readerfun_t*) dlsym(dlh, "plugin_reader");
 if (!readplugfun) { fprintf (stderr, "dlsym failed: %s\n", dlerror());
                     exit(EXIT_FAILURE); };

当然,在您的插件源代码中(例如在plugin1.cc中),您将定义

代码语言:javascript
复制
 extern "C" int plugin_reader (FILE*inf) { // etc...

您可以在插件中定义一些构造函数(或析构函数)(请参见GCC函数属性);应该在dlopen (或dlclose)时调用该函数。在C++中,您应该简单地使用静态对象。(在dlopen时调用它们的构造函数,在dlclose时调用它们的析构函数;因此函数属性的名称)。

在程序调用结束时

代码语言:javascript
复制
 dlclose(dlh), dlh = NULL;

实际上,您可以执行大量(可能是100万) dlopen调用。

您通常希望将您的主程序与-rdynamic链接,以便从插件中看到它的符号。

代码语言:javascript
复制
gcc -rdynamic prog1.o prog2.o -o yourprog -ldl

阅读程序库HowTo & C++ dlopen迷你HowTo & Drepper的论文:

最重要的部分是定义并记录一个插件约定(即“协议”),即插件中所需的一组函数(和API),以及如何使用它们,调用它们的顺序,内存所有权策略等等。如果允许几个类似的插件,您的主程序中可能有一些记录良好的钩子,这些钩子调用相关的dlsym-ed插件的所有dlsym-ed函数。例如:GCC插件惯例GNU制作模块Gedit插件 .

票数 6
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/26669302

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档