什么是C ++插件系统的安全?

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

让我们来实践一下吧,在这方面留下不太有用的C ++标准,不要一分钟。 如果我想为支持C ++插件的Windows和Mac(以及可选的Linux)编写应用程序,并且如果我想为插件作者提供相当多的编译器select(比如不超过2年的Visual C ++版本,GCC或者Intel的C ++编译器),我可以指望什么C ++特性?

当然,我认为插件将被写入特定的平台。

关于我的头顶,下面是我能想到的一些C ++特性,我认为是这样的答案:

  • vtable的布局,通过抽象类来使用对象? (是)
  • 内置types,指针? (是)
  • 结构,工会? (是)
  • exception? (没有)
  • 外部“C”function? (是)
  • 带有内置参数types的stdcall非外部“C”函数? (是)
  • 非stdcall非外部“C”函数与用户定义的参数types? (没有)

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

卡尔

Dobb博士的杂志有一篇文章构build你自己的插件框架:第1部分 ,这个主题很不错。 这是一系列文章的开始,涵盖了C / C ++跨平台插件框架的架构,开发和部署。

您可能还想考虑通过脚本界面来replace传统的插件界面。 对于C / C ++中的几种脚本语言,已经有一些非常好的绑定,已经解决了你的问题。 build立在它们之上可能不是一个坏主意。 例如,看看Boost.Python 。

Qt有一个很好的系统,我以前用过的插件。 它使用Qt的元对象系统来克服通常在尝试开发C ++插件时遇到的许多问题。

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

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

我认为你安全地创build一个插件系统的基础上:

  • 将插件function封装到库中(.dll,.so等)
  • 要求插件公开关键的C语言导出。
  • 要求插件实现(并返回一个指针/引用)一个抽象的C ++接口。

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

Matthew Wilson的书“ Imperfect C ++”有很好的信息。

这里的build议似乎是:只要你使用相同(或相等)的编译器,你可以使用C ++,否则你最好使用C作为C ++代码的接口。

ACE有一个跨平台的插件架构。

查看:

  1. ACE DLL
  2. ACE DLLpipe理器

我会build议查看这本书
ACE程序员指南

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

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

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

生活在主引擎中的更大的函数通过导出的C函数调用(插件调用MyObject_somefunction(MyObject * obj),在引擎中调用obj-> somefunction())。 如果调用一个C函数对你来说是丑陋的,那么在插件包含头文件的情况下,如果有一些头文件欺骗,请使用成员函数#defined来调用C函数:

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

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

基本上,我使用的技巧,目标是保持总体平台独立性,只是C出口和头文件技巧。