静态库中的对象注册

bee*_*f2k 7 c++ plugins static-libraries

我已经实现了一个非常基本的"插件系统"作为静态库的一部分.每个"插件"都实现了对特定图像格式的支持,例如GIF,JPEG等.此外,我还有一个Singleton(一个叫做的类PluginManager),它保存了所有可用插件的列表.

棘手的部分是我想通过在项目文件中添加或删除源文件来禁用/启用插件.为实现此目的,每个插件都会创建一个全局变量(具有不同的名称),并在该类的构造函数中注册该插件PluginManager.

对于JPEG格式,这样的东西......

struct JPEGPlugin
{
  // constructor will register plugin
  JPEGPlugin()
  {
    PluginManager::Singleton().RegisterPlugin(this);
  }

  // plenty of other code
  ...
};

JPEGPlugin jpeg_instance;  // instantiate in global scope
Run Code Online (Sandbox Code Playgroud)

然而,虽然这在理论上完美地起作用,但是当将该静态库链接到其他代码以构建可执行文件时它会失败.只要此可执行文件不访问插件全局变量(如jpeg_instance),链接器就不会看到连接(他完全忽略了构造函数的副作用),并且不包含最终可执行文件中的代码.换句话说,JPEG插件在最终应用程序中不可用.

多年来我遇到过几次问题,我总是在网上寻找解决方案.每次,我只是发现页面基本上说这是一个已知的问题,我必须忍受它.

但也许有人知道如何让这个工作?

Har*_*ich 3

我不知道这是否是您解决此问题的方法的解决方案,但我们在对象工厂的静态注册方面遇到了类似的问题,在 Visual Studio 中,我们通过声明 __declspec(dllexport) 涉及的类来解决它,这是必要的即使涉及的库不是 dll。但如果没有这个,链接器将忽略未引用的类。

我们使用的注册表解决方案有点不同,并且不涉及堆栈分配的对象。我从 CPP 单元中提取了部分,这也是我发现 __declspec 方法 iirc 的地方。

[编辑] 我们还必须#include从代码的某些部分声明已注册的类。