用 C 或 C++ 实现插件系统
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/708527/
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
Implementing A Plugin System in C or C++
提问by ixo
What are your tips on implementing a plugin style system?
你对实现插件风格系统有什么建议?
回答by unwind
In C (and I think C++ too although I haven't done it myself), this is most typically done using dynamically loaded modules. The API:s for such are platform-dependent.
在 C 中(我也认为是 C++,虽然我自己没有做过),这通常是使用动态加载的模块来完成的。API:s 是平台相关的。
On POSIX (Linux), you use the dlopen()
family of functions. Basically you build your plugin separately, then load it at run-time, look up its symbols by name, and can then call them.
在 POSIX (Linux) 上,您使用dlopen()
函数系列。基本上你单独构建你的插件,然后在运行时加载它,按名称查找它的符号,然后可以调用它们。
For Win32, there is LoadLibrary()
which does something very similar, you build your code into a DLL.
对于 Win32,有LoadLibrary()
一些非常相似的东西,您将代码构建到 DLL 中。
For a handy wrapper that makes all of these easy and transparent, check out GLib's GModuleAPI.
对于使所有这些变得简单和透明的方便的包装器,请查看 GLib 的GModuleAPI。
回答by RogerV
In the '92/'93 time frame I worked on a plugin architecture for Aldus PageMaker, which was coded in C++. PageMaker was built on a C++ OOP framework called VAMP, which assisted its portability between Mac OS and Windows.
在 92/93 年的时间框架内,我为 Aldus PageMaker 开发了一个插件架构,它是用 C++ 编码的。PageMaker 建立在名为 VAMP 的 C++ OOP 框架之上,这有助于它在 Mac OS 和 Windows 之间的可移植性。
So we tried to use the features of C++ to build a plugin architecture. This proved to be very problematic for C++ classes due to the so-called brittle base class problem. I proceeded to write a paper that was published in journals and that I presented at OOPSLA '93 in a reflection workshop. I also made contact with Bjarne Stroustrup at a Usenix conference in Portland and proceeded to dialog with him for several months, where he championed the issue of dealing with the brittle base class problem on my behalf. (Alas, other issues were deemed more important at that time.)
所以我们尝试利用C++的特性来构建插件架构。由于所谓的脆弱基类问题,这对于 C++ 类来说是非常有问题的。我接着写了一篇论文,该论文发表在期刊上,并在 OOPSLA '93 的一个反思研讨会上发表。我还在波特兰的 Usenix 会议上与 Bjarne Stroustrup 取得了联系,并与他进行了几个月的对话,在那里他代表我支持处理脆弱的基类问题。(唉,当时其他问题被认为更重要。)
Microsoft introduced the COM/DCOM system and for that platform that was looked on as a viable solution to the problem. C++ could be used as an implementation language for COM via abstract classes used to define COM interfaces.
Microsoft 引入了 COM/DCOM 系统,并针对该平台将其视为问题的可行解决方案。通过用于定义 COM 接口的抽象类,C++ 可以用作 COM 的实现语言。
However, these days developers shun away from COM/DCOM.
然而,现在开发人员回避 COM/DCOM。
In contrast, NeXT devised a plugin architecture using Objective C in the early 90s in the NeXT Step framework. Today that lives on vibrantly in Mac OS X on Apple's computers and important platforms such as the iPhone.
相比之下,NeXT 在 90 年代初期在 NeXT Step 框架中使用 Objective C 设计了一个插件架构。今天,它在 Apple 计算机和 iPhone 等重要平台上的 Mac OS X 中充满活力。
I submit Objective C enabled solving the plugin problem in a superior manner.
我提交了 Objective C,以更好的方式解决插件问题。
I personally regard the brittle base class problem of C++ to be it's most fatal flaw.
我个人认为 C++ 脆弱的基类问题是它最致命的缺陷。
If were building a plugin architecture with the C-based family of languages, would do so using Objective C.
如果要使用基于 C 的语言系列构建插件架构,将使用 Objective C。
回答by AshleysBrain
The best platform and language neutral advice I can give is this:
我能给出的最好的平台和语言中立建议是:
Design your entire app around the plugin SDK.
围绕插件 SDK 设计您的整个应用程序。
IMO, a plugin SDK should not be an afterthought. If you design your app to basically be an empty shell which loads plugins, then the core features are implemented in your own SDK, you get the following benefits:
IMO,插件 SDK 不应该是事后的想法。如果您将您的应用程序设计为基本上是一个加载插件的空壳,那么核心功能在您自己的 SDK 中实现,您将获得以下好处:
- High modularity of components, and clear separation of purpose (it kind of forces your architecture to be good)
- It forces your SDK to be really good
- It allows other third party developers to make extremely powerful, core-level features as well
- New developers/hires can easily start work on a major new feature without having to touch the main app - they can do all their work in a plugin (which prevents them screwing up anything else)
- 组件的高度模块化,以及明确的目的分离(这会迫使您的架构变得良好)
- 它迫使你的 SDK 非常好
- 它也允许其他第三方开发人员制作极其强大的核心级功能
- 新的开发人员/雇员可以轻松开始一项主要的新功能,而无需接触主应用程序 - 他们可以在插件中完成所有工作(这可以防止他们搞砸其他任何事情)
In C/C++, you probably use dynamic link libraries and either function pointers (C) or interfaces (classes solely consisting of pure virtual methods, for C++). However even if you use Javascript, I'd still recommend the above architecture.
在 C/C++ 中,您可能使用动态链接库和函数指针 (C) 或接口(对于 C++,仅由纯虚拟方法组成的类)。但是,即使您使用 Javascript,我仍然推荐上述架构。
回答by Chris Lutz
This may not be what you're looking for, but you could embed a scripting language in your application, such as Lua. Lua was designed to be embedded in other programs and used as a scripting language for writing plugins. I believe it's fairly easy to add the Lua interpreter to your program, though I don't know Lua so I can't vouch for how effective of a solution this would be. Others with more experience with Lua, please add comments about your experience with embedding Lua in another application.
这可能不是您想要的,但您可以在应用程序中嵌入脚本语言,例如 Lua。Lua 旨在嵌入其他程序并用作编写插件的脚本语言。我相信将 Lua 解释器添加到您的程序中是相当容易的,尽管我不了解 Lua,所以我无法保证这将是多么有效的解决方案。其他对 Lua 有更多经验的人,请添加关于您在另一个应用程序中嵌入 Lua 的经验的评论。
This would, of course, mean that your plugins need to be written in Lua. If you don't like Lua then the de-factostandard Perl, Python and Ruby interpreters are all written in C, and can be embedded in a C program. I know of a number of programs that use these languages as scripting language extensions.
当然,这意味着您的插件需要用 Lua 编写。如果您不喜欢 Lua,那么事实上的标准 Perl、Python 和 Ruby 解释器都是用 C 编写的,并且可以嵌入到 C 程序中。我知道许多使用这些语言作为脚本语言扩展的程序。
However, I don't know what you're looking for, as your question is a little vague. Perhaps more information about what you want people to be able to do with said plugins would be appropriate. For some tasks, a full-blown scripting language may be a bit overkill.
但是,我不知道您在寻找什么,因为您的问题有点含糊。也许有关您希望人们能够使用所述插件做什么的更多信息是合适的。对于某些任务,成熟的脚本语言可能有点矫枉过正。
回答by Andrew Ross
Qt provides QPluginLoader: http://qt-project.org/doc/qt-4.8/qpluginloader.html
Qt 提供 QPluginLoader:http://qt-project.org/doc/qt-4.8/qpluginloader.html
If you need/want more fine grained control, Qt also provides a means to load libraries on the fly with QLibrary: http://qt-project.org/doc/qt-4.8/qlibrary.html
如果您需要/想要更细粒度的控制,Qt 还提供了一种使用 QLibrary 动态加载库的方法:http: //qt-project.org/doc/qt-4.8/qlibrary.html
Even better, these are portable across platforms.
更好的是,这些可以跨平台移植。
回答by Torsten
Look at Poco Class Loader, it can be interesting for you.
看看Poco Class Loader,它对你来说可能很有趣。
回答by lothar
It's best to use a framework like ACE (http://www.cs.wustl.edu/~schmidt/ACE.html) that shields you (as good as possible) from platform specific coding.
最好使用像 ACE ( http://www.cs.wustl.edu/~schmidt/ACE.html) 这样的框架来保护您(尽可能好)免受平台特定编码的影响。
ACE contains a plugin framework that is based on shared libraries that you can use to create dynamically assembled applications.
ACE 包含一个基于共享库的插件框架,您可以使用它来创建动态组装的应用程序。
For a higher level abstraction check out CIAO (http://www.cs.wustl.edu/~schmidt/CIAO.html) the Open Source C++ implementation of the CORBA Component Model.
对于更高级别的抽象,请查看 CIAO ( http://www.cs.wustl.edu/~schmidt/CIAO.html) CORBA 组件模型的开源 C++ 实现。
回答by Jeremiah
I have written an article about how to implement a plugin system using Dynamic Linking Libraries. The article is written from the point-of-view of a Windows programmer but the technique can be applied to a Linux/Unix type environment.
我写了一篇关于如何使用动态链接库实现插件系统的文章。这篇文章是从 Windows 程序员的角度编写的,但该技术可以应用于 Linux/Unix 类型的环境。
The article can be found here: http://3dgep.com/?p=1759
这篇文章可以在这里找到:http: //3dgep.com/?p=1759
The main point is, you should create a "common" DLL that is implicitly linked by both the main application (the core application) and by the plugin implementations. The plugins can then be explicitly linked and loaded dynamically at run-time by the core application.
要点是,您应该创建一个由主应用程序(核心应用程序)和插件实现隐式链接的“公共”DLL。然后,核心应用程序可以在运行时显式链接和动态加载插件。
The article also shows how you can safely share static (singleton) instance of a class across multiple DLLs by using the "common" DLL.
本文还展示了如何使用“公共”DLL 跨多个 DLL 安全地共享类的静态(单例)实例。
The article also shows how you can export a "C" function or variables from a DLL and use the exported functions in the application at run-time.
本文还展示了如何从 DLL 导出“C”函数或变量,并在运行时在应用程序中使用导出的函数。
回答by dirkgently
I have had some success using a fairly naive system:
我使用一个相当幼稚的系统取得了一些成功:
- Create API Specification for plug-ins
- Use a singleton plug-in manager
- Use LoadLibrary/GetProcAddress based run time dynamic linking
- Implement Inversion of control based event handling for notifying the plug-ins
- 为插件创建 API 规范
- 使用单例插件管理器
- 使用基于 LoadLibrary/GetProcAddress 的运行时动态链接
- 实现基于控制反转的事件处理以通知插件
回答by none
This podcast on plugin architecturesmight also be interesting.
这个关于插件架构的播客也可能很有趣。