什么对 C++ 插件系统来说是安全的?
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/43322/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
What's safe for a C++ plug-in system?
提问by Carl Seleborg
Plug-in systems in C++ are hard because the ABI is not properly defined, and each compiler (or version thereof) follows its own rules. However, COM on Windows shows that it's possible to create a minimal plug-in system that allows programmers with different compilers to create plug-ins for a host application using a simple interface.
C++ 中的插件系统很难,因为 ABI 没有正确定义,并且每个编译器(或其版本)都遵循自己的规则。然而,Windows 上的 COM 表明可以创建一个最小的插件系统,允许使用不同编译器的程序员使用简单的界面为主机应用程序创建插件。
Let's be practical, and leave the C++ standard, which is not very helpful in this respect, aside for a minute. If I want to write an app for Windows and Mac (and optionally Linux) that supports C++ plug-ins, and if I want to give plug-in authors a reasonably large choice of compilers (say less than 2 year old versions of Visual C++, GCC or Intel's C++ compiler), what features of C++ could I count on?
让我们实际一点,暂时将 C++ 标准放在一边,这在这方面不是很有帮助。如果我想为 Windows 和 Mac(以及可选的 Linux)编写一个支持 C++ 插件的应用程序,并且如果我想为插件作者提供相当多的编译器选择(比如不到 2 年的 Visual C++ 版本) 、GCC 或英特尔的 C++ 编译器),我可以指望 C++ 的哪些功能?
Of course, I assume that plug-ins would be written for a specific platform.
当然,我假设插件是为特定平台编写的。
Off the top of my head, here are some C++ features I can think of, with what I think is the answer:
在我的脑海中,这里有一些我能想到的 C++ 特性,我认为答案是:
- vtable layout, to use objects through abstract classes? (yes)
- built-in types, pointers? (yes)
- structs, unions? (yes)
- exceptions? (no)
- extern "C" functions? (yes)
- stdcall non-extern "C" functions with built-in parameter types? (yes)
- non-stdcall non-extern "C" functions with user-defined parameter types? (no)
- vtable 布局,通过抽象类使用对象?(是的)
- 内置类型,指针?(是的)
- 结构,联合?(是的)
- 例外?(不)
- 外部“C”函数?(是的)
- 具有内置参数类型的 stdcall 非外部“C”函数?(是的)
- 具有用户定义参数类型的非标准调用非外部“C”函数?(不)
I would appreciate any experience you have in that area that you could share. If you know of any moderately successful app that has a C++ plug-in system, that's cool too.
如果您在该领域拥有任何可以分享的经验,我将不胜感激。如果您知道任何具有 C++ 插件系统的中等成功的应用程序,那也很酷。
Carl
卡尔
采纳答案by Serge
Dr Dobb's Journal has an article Building Your Own Plugin Framework: Part 1which is pretty good reading on the subject. It is the start of a series of articles which covers the architecture, development, and deployment of a C/C++ cross-platform plugin framework.
Dr Dobb's Journal 有一篇文章构建你自己的插件框架:第 1 部分,这是关于这个主题的很好的读物。它是一系列文章的开始,涵盖了 C/C++ 跨平台插件框架的架构、开发和部署。
回答by Konrad Rudolph
You might also want to consider replacing the conventional plugin interface by a scripting interface. There are some very good bindings for several scripting languages in C/C++ that have already solved your problem. It might not be a bad idea to build on top of them. For example, have a look at Boost.Python.
您可能还想考虑用脚本接口替换传统的插件接口。对于 C/C++ 中的几种脚本语言,有一些非常好的绑定,它们已经解决了您的问题。在它们之上构建可能不是一个坏主意。例如,看看Boost.Python。
回答by KeyserSoze
Qthas a very nice system for plugins that I've used in the past. It uses Qt's meta-object system to overcome many of the problems typically found when trying to develop C++ plugins.
Qt有一个非常好的插件系统,我过去使用过。它使用 Qt 的元对象系统来克服在尝试开发 C++ 插件时通常会发现的许多问题。
One example is how Q_DECLARE_INTERFACE
works, to prevent you from using an incompatible plugin. Another is the build key, to make sure you load the correct plugin for your architecture, OS, compiler. If you don't use Qt's plugin system, these are things you will have to worry about and invent solutions for on your own. It's not necessarily rocket science, and I'm not saying you'd fail at it, but the guys at Trolltech are pretty smart and have spent a while thinking about it, and I'd rather use what they created than reinvent the wheel myself.
一个例子是如何Q_DECLARE_INTERFACE
工作,以防止您使用不兼容的插件。另一个是构建密钥,以确保为您的架构、操作系统、编译器加载正确的插件。如果您不使用 Qt 的插件系统,这些是您将不得不担心并自行发明解决方案的事情。这不一定是火箭科学,我并不是说你会失败,但 Trolltech 的人非常聪明并且花了一段时间思考它,我宁愿使用他们创造的东西而不是自己重新发明轮子.
Another example is that RTTI typically doesn't work across DLL boundaries, but when using Qt, things like qobject_castwhich rely on the meta-object system do work across DLL boundaries.
另一个例子是RTTI通常不能跨 DLL 边界工作,但是在使用 Qt 时,像qobject_cast这样依赖元对象系统的东西确实可以跨 DLL 边界工作。
回答by KeyserSoze
I think you are safe creating a plugin system based on:
我认为您可以安全地基于以下内容创建插件系统:
- Packaging of plugin functionality into library (.dll, .so, etc.)
- Requiring that the plugin expose key C-language exports.
- Requiring that the plugin implement (and return a pointer/reference to) an abstract C++ interface.
- 将插件功能打包到库中(.dll、.so 等)
- 要求插件公开关键的 C 语言导出。
- 要求插件实现(并返回一个指针/引用)一个抽象的 C++ 接口。
Probably the most successful C++ plugin system: good old Adobe Photoshop. And if not that, one of the virtual synth formats such as VSTi etc.
可能是最成功的 C++ 插件系统:好老的Adobe Photoshop。如果不是这样,虚拟合成器格式之一,如 VSTi 等。
回答by Peter Stuifzand
The book Imperfect C++ by Matthew Wilsonhas a nice info about this.
Matthew Wilson所著的《Imperfect C++》一书对此有很好的介绍。
The advice in the seems to be: as long as you use the same (or equivelant) compiler, you can use C++, otherwise you're better of using C as an interface on top of your C++ code.
中的建议似乎是:只要您使用相同(或等效)的编译器,就可以使用 C++,否则最好使用 C 作为 C++ 代码之上的接口。
回答by Martin York
ACEhas a cross platform plug-in architecture.
ACE具有跨平台插件架构。
Check out:
查看:
I would suggest checking out the book
The ACE Programmer's Guide
我建议查看这本书
The ACE Programmer's Guide
回答by Rodrigo Strauss
Firefox runs on XPCOM (http://www.mozilla.org/projects/xpcom/). It's inspired by Microsoft COM but it's multiplatform.
Firefox 在 XPCOM ( http://www.mozilla.org/projects/xpcom/)上运行。它的灵感来自 Microsoft COM,但它是多平台的。
回答by Jim Buck
I have my own game engine that has a C++ plug-in system.
我有自己的游戏引擎,它有一个 C++ 插件系统。
I have some code in header files so it gets put into the plugin's compilation unit.
我在头文件中有一些代码,所以它被放入插件的编译单元。
Larger functions that live in the main engine are called via an exported C function (plugin calls MyObject_somefunction(MyObject *obj) which in the engine just calls obj->somefunction()). If calling a C function is ugly for your taste, then with some header trickery, when the header is included in the plugin, have the member function #defined to call the C function:
存在于主引擎中的较大函数通过导出的 C 函数调用(插件调用 MyObject_somefunction(MyObject *obj),在引擎中只调用 obj->somefunction())。如果调用 C 函数对您来说很丑陋,那么使用一些标题技巧,当标题包含在插件中时,让成员函数 #defined 调用 C 函数:
#if defined(IN_THE_PLUGIN)
void MyObject::somefunction() { MyObject_somefunction(this); }
#endif
Virtual functions either have to be pure or the code lives in the header file. If I'm not inheriting from a class and merely just instancing one, virtual function code can live in the engine, but then the class must export some C functions for creating and destroying the object that is called from the plugin.
虚函数要么必须是纯函数,要么代码位于头文件中。如果我不是从一个类继承而只是实例化一个,那么虚拟函数代码可以存在于引擎中,但是该类必须导出一些 C 函数来创建和销毁从插件调用的对象。
Basically, the tricks that I have used, with the goal being to maintain total platform independence, just amount to C exports and header file tricks.
基本上,我使用的技巧,目标是保持完全平台独立性,只是 C 导出和头文件技巧。