beef2k beef2k - 1 month ago 14
C++ Question

Object Registration in Static Library

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?

Answer

I don't know if this a solution for the way you solved this problem, but we had a similar problem with static registration of an object factory and in Visual Studio we solved it by declaring the classes involved with __declspec(dllexport) this was necessary even though the libraries involved were not dlls. But without this the linker would omit the not referenced classes.

The registry solution we worked a little bit different and did not involve Stack allocated objects. I lifted parts from CPP-unit, that is also where i discovered the __declspec approach iirc.

[edit] We also had to #include the declaration for the registered class from some part of the code.

Comments