I have implemented a very basic "plug-in system" as part of a static library. Each "plug-in" implements the support for a specific image format, e.g. GIF, JPEG, etc.. Furthermore, I have a Singleton (a class called PluginManager
) that keeps a list of all available plug-ins.
The tricky part is that I want to disable/enable the plug-ins by adding or removing their source files from the project file. To achieve this, each plug-in creates a global variable (with different names) and registers the plug-in in the constructor of that class to PluginManager
.
Something like this for the JPEG format...
struct JPEGPlugin
{
// constructor will register plugin
JPEGPlugin()
{
PluginManager::Singleton().RegisterPlugin(this);
}
// plenty of other code
...
};
JPEGPlugin jpeg_instance; // instantiate in global scope
However, while this works perfectly in theory, it fails when linking this static library to other code to build an executable. As long as this executable does not access the plugin globals (like jpeg_instance
), the linker does not see a connection (he completely ignores the side-effects of the constructor) and does not include the code in the final executable. In other words, the JPEG plug-in is not available in the final app.
I ran into the problems a couple of times over the years, and I always searched the net for solutions. Each time, I just found pages that basically say that it's a known problem and that I have to live with it.
But maybe someone on SO knows how to make this working?