What are your tips on implementing a plugin style system?
-
Related - if not duplicate - http://stackoverflow.com/questions/384121/creating-a-module-system-dynamic-loading-in-c – ChrisF Apr 03 '13 at 09:14
-
1Have a look at [this tutorial](http://sourcey.com/building-a-simple-cpp-cross-platform-plugin-system/). They have released this tutorial as a working cross-platform project named [Pluga](http://sourcey.com/pluga/) which uses a library named [LibSourcey](https://github.com/sourcey/libsourcey). – aggregate1166877 May 24 '15 at 18:59
11 Answers
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.
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.
For Win32, there is LoadLibrary()
which does something very similar, you build your code into a DLL.
For a handy wrapper that makes all of these easy and transparent, check out GLib's GModule API.

- 391,730
- 64
- 469
- 606
-
For Win32 I would recommend LoadLibraryEx with the LOAD_WITH_ALTERED_SEARCH_PATH flag set. – dalle Apr 02 '09 at 06:48
-
that's the way I do it. C++ doesn't have a defined ABI so you can't reliably use it to load C++ classes dynamically. whereas c does. If you need c++ loading, you must expose all your modules with a c interface (eg COM does it by exposing 4 functions) – gbjbaanb Apr 04 '09 at 14:16
-
3Another wrapper around the whole mess is Qt's plugin system. It does all the behind-the-scenes maneuvering to allow you to load C++ stuff from a module safely. – Michael Kohne Apr 02 '13 at 21:54
-
So at the base level, plugins are basically dlls, which can be loaded by a program. The program can enumerate all its plugins at startup, or during runtime (if a new plugin is added) and they add functionality to the original program. But how are they added into the base program? My guess is: hooking. – KeyC0de Nov 25 '20 at 18:17
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.
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.)
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.
However, these days developers shun away from 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.
I submit Objective C enabled solving the plugin problem in a superior manner.
I personally regard the brittle base class problem of C++ to be it's most fatal flaw.
If were building a plugin architecture with the C-based family of languages, would do so using Objective C.

- 3,826
- 4
- 28
- 32
-
-
the idea is that if you change the base class, it can break all derived classes - however, I think this applies to all oo plugins. It certainly applies to jscript.net: http://blogs.msdn.com/ericlippert/archive/2004/01/07/virtual-methods-and-brittle-base-classes.aspx – gbjbaanb Apr 04 '09 at 14:08
-
1Here a citation of one of my papers: http://citeseerx.ist.psu.edu/viewdoc/summary?doi=10.1.1.51.418 At the bottom page there is a View or Download link to get the .pdf: http://citeseerx.ist.psu.edu/viewdoc/download;jsessionid=1B865C7B3133C75949ECE12B20D3D140?doi=10.1.1.51.418&rep=rep1&type=pdf – RogerV Apr 05 '09 at 01:50
-
3I've now written a blog post to sum all this up: After 17 years is it too late to fix C++ runtime extensibility? http://humbleblogger.blogspot.com/2009/04/after-17-years-is-it-too-late-to-fix-c.html – RogerV Apr 05 '09 at 06:54
The best platform and language neutral advice I can give is this:
Design your entire app around the plugin 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:
- 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)
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.

- 22,335
- 15
- 88
- 124
Qt provides 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
Even better, these are portable across platforms.

- 91
- 1
- 2
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.
This would, of course, mean that your plugins need to be written in Lua. If you don't like Lua then the de-facto standard 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.
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.

- 73,191
- 16
- 130
- 183
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.
The article can be found here: 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.
The article also shows how you can safely share static (singleton) instance of a class across multiple DLLs by using the "common" 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.

- 441
- 6
- 5
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 contains a plugin framework that is based on shared libraries that you can use to create dynamically assembled applications.
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.

- 19,853
- 5
- 45
- 59
I have written a plugin library Pugg that loads C++ classes from dll files and here is the logic I used:
User exports a c function from dll that has a unique name. This name has to be unique enough as functions cannot be distinguished using their arguments while loading from dlls.
C function registers one or several factory classes called "Driver". Every Driver class is associated with a string. When the main application wants to create a class, it gathers the related factory class using the associated string. I also implemented a version checking system to not load old plugins.
Dll loading is accomplished using the LoadLibraryA and GetProcAddress functions (Pugg currently works on windows).
One thing worth mentioning is that main application and dlls should be compiled using the same compiler and using the same compilation options (release/debug modes, optimization settings, stl versions etc...). Otherwise there might be issues with mapping of classes.

- 519
- 6
- 18
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

- 108,024
- 16
- 131
- 187