我一直在玩弄,在C中编写一个小型IRC框架,我现在要扩展一些核心功能 - 但除此之外,我希望它可以通过插件进行扩展!
到目前为止,每当我写一些IRC相关的东西时(我写了很多东西,现在大约有6种不同的语言......我很着火!)并且实际上继续实现了一个插件架构,它是在一个内部解释性的语言,有设施(读取:滥用),就像在Ruby中干扰整个脚本文件eval
一样(糟糕!)。
现在我想在C中滥用某些东西!
基本上我可以做三件事
我喜欢第三个,如果可能,请避开其他两个选项。也许我是某种形式的受虐狂,但我认为这对于学习目的来说既有趣又有用。
逻辑思考,明显的“痛苦链”将是(从最低到最高)2 - > 1 - > 3,原因很简单,libdl正在处理原始代码,这些代码可能(并且将会)在我的脸上爆炸。
所以这个问题告诉你,stackoverflow的其他用户,你认为libdl能胜任这个任务,还是一个现实的想法?
答案 0 :(得分:3)
libdl
非常适合插件架构 - 在某些范围内:-)。它在很多不同的软件中用于这种目的很多。它适用于主程序和插件之间有明确定义的API /接口的情况,并且许多不同的插件实现相同的API /接口。例如,您的IRC客户端可能具有实现不同IM协议(Jabber,MSN,Sametime等...)的网关的插件 - 所有这些都非常相似,因此您可以使用诸如“发送消息”之类的功能来定义API “,”检查回复“等 - 并编写一堆插件,每个插件都实现了不同的协议。
它运行得不好的情况是你希望让插件对主程序的行为进行任意改变 - 例如,Firefox插件可以改变浏览器选项卡的行为,它们的外观,添加/删除按钮等。这种事情在动态语言中更容易实现(因此,为什么很多Firefox都是用javascript实现的),如果这是你想要的那种自定义,你最好选择你的选项(2),并编写一个很多用脚本语言的UI ......
答案 1 :(得分:3)
dlopen()
/ dlsym()
可能是最简单的方法。一些愚蠢的伪代码:
int run_module(const char *path, char **args)
{
void *module;
void (*initfunc)(char **agrs);
int rc = 0;
module = dlopen(path, RTLD_NOW);
if (module == NULL)
err_out("Could not open module %s", path);
initfunc = dlsym(module, "module_init");
if (initfunc == NULL) {
dlclose(module);
err_out("Could not find symbol init_func in %s", path);
}
rc = initfunc(args);
dlclose(module);
return rc;
}
当然,你会想要更多的错误检查,以及实际做了一些有用的代码:)然而,非常简单方便地编写插件在这对中的架构中,发布一个简单的规范,让其他人也这样做。
你可能想要更多类似于load_module()
的内容,上面只是加载SO,寻找一个入口点并阻塞直到该入口点退出。
这并不是说编写自己的脚本语言是个坏主意。人们可以编写复杂的过滤器,响应者等,而不必经历很多麻烦。也许两者都是个好主意。我不知道你是否想要一个完整的LUA解释器......也许你可以想出一些简单的基于正则表达式采取行动的东西。
尽管如此,插入模块不仅可以让您的生活变得更简单,而且还可以帮助您建立一个人们社区,围绕您制作的任何东西进行开发。
答案 2 :(得分:1)
有很多现有的C程序使用dlopen()
/ dlsym()
来实现插件架构(包括多个与IRC相关的架构);所以是的,这绝对取决于任务。