47

C++ 中的插件系统很难,因为 ABI 没有正确定义,并且每个编译器(或其版本)都遵循自己的规则。然而,Windows 上的 COM 表明,可以创建一个最小的插件系统,允许具有不同编译器的程序员使用简单的接口为主机应用程序创建插件。

让我们切合实际,暂时搁置在这方面没有多大帮助的 C++ 标准。如果我想为 Windows 和 Mac(以及可选的 Linux)编写一个支持 C++ 插件的应用程序,并且如果我想为插件作者提供相当多的编译器选择(比如不到 2 年的 Visual C++ 版本) 、GCC 或 Intel 的 C++ 编译器),我可以依靠 C++ 的哪些特性?

当然,我假设插件是为特定平台编写的。

在我的脑海中,这里有一些我能想到的 C++ 特性,我认为这就是答案:

  • vtable 布局,通过抽象类使用对象?(是的)
  • 内置类型,指针?(是的)
  • 结构体,联合体?(是的)
  • 例外?(不)
  • 外部“C”函数?(是的)
  • 具有内置参数类型的 stdcall 非外部“C”函数?(是的)
  • 具有用户定义参数类型的非标准调用非外部“C”函数?(不)

如果您在该领域有任何经验可以分享,我将不胜感激。如果您知道任何具有 C++ 插件系统的成功应用程序,那也很酷。

卡尔

4

8 回答 8

25

Dobb 博士的期刊有一篇文章构建您自己的插件框架:第 1 部分,这是关于该主题的非常好的阅读材料。这是涵盖 C/C++ 跨平台插件框架的架构、开发和部署的系列文章的开始。

于 2008-09-04T08:11:53.327 回答
6

您可能还想考虑用脚本接口替换传统的插件接口。对于 C/C++ 中的几种脚本语言,有一些非常好的绑定已经解决了您的问题。在它们之上构建可能不是一个坏主意。例如,看看Boost.Python

于 2008-09-04T09:09:07.853 回答
6

Qt为我过去使用过的插件提供了一个非常好的系统。它使用 Qt 的元对象系统来克服在尝试开发 C++ 插件时通常会遇到的许多问题。

一个例子是如何Q_DECLARE_INTERFACE工作,以防止您使用不兼容的插件。另一个是build key,以确保为您的架构、操作系统、编译器加载正确的插件。如果您不使用 Qt 的插件系统,那么您将不得不担心这些事情并自己发明解决方案。这不一定是火箭科学,我也不是说你会失败,但奇趣科技的人很聪明,花了一段时间思考这个问题,我宁愿使用他们创造的东西,也不愿自己重新发明轮子.

另一个例子是RTTI通常不能跨 DLL 边界工作,但是在使用 Qt 时,依赖元对象系统的qobject_cast之类的东西确实可以跨 DLL 边界工作。

于 2008-10-07T01:22:38.563 回答
3

我认为您可以安全地创建基于以下内容的插件系统:

  • 将插件功能打包到库中(.dll、.so 等)
  • 要求插件公开关键的 C 语言导出。
  • 要求插件实现(并返回指针/引用)抽象 C++ 接口。

可能是最成功的 C++ 插件系统:好老的Adob​​e Photoshop。如果不是这样,虚拟合成器格式之一,如 VSTi 等。

于 2008-09-04T09:47:25.220 回答
3

Matthew Wilson所著的《Imperfect C++ 》一书对此提供了很好的信息。

中的建议似乎是:只要您使用相同(或等效的)编译器,您就可以使用 C++,否则您最好在 C++ 代码之上使用 C 作为接口。

于 2008-09-04T09:49:58.897 回答
2

我有自己的游戏引擎,它有一个 C++ 插件系统。

我在头文件中有一些代码,因此它被放入插件的编译单元中。

存在于主引擎中的较大函数通过导出的 C 函数调用(插件调用 MyObject_somefunction(MyObject *obj),在引擎中只调用 obj->somefunction())。如果调用 C 函数不符合您的口味,那么使用一些头文件技巧,当头文件包含在插件中时,使用成员函数 #defined 来调用 C 函数:

#if defined(IN_THE_PLUGIN)
void MyObject::somefunction() { MyObject_somefunction(this); }
#endif

虚函数要么必须是纯函数,要么代码存在于头文件中。如果我不是从一个类继承而只是实例化一个类,那么虚拟函数代码可以存在于引擎中,但是该类必须导出一些 C 函数来创建和销毁从插件调用的对象。

基本上,我使用的技巧,目的是保持完全的平台独立性,只是 C 导出和头文件技巧。

于 2008-09-04T08:58:26.413 回答
2

ACE具有跨平台插件架构。

查看:

  1. ACE DLL
  2. ACE DLL 管理器

我建议查看
《ACE 程序员指南》这本书

于 2008-10-07T02:54:54.620 回答
2

Firefox 在 XPCOM ( http://www.mozilla.org/projects/xpcom/ ) 上运行。它的灵感来自 Microsoft COM,但它是多平台的。

于 2009-08-17T03:20:59.147 回答