我已经实现了一个非常基本的“插件系统”作为静态库的一部分。每个“插件”实现了对特定图像格式的支持,例如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
然而,虽然这在理论上完美无缺,但在将此静态库链接到其他代码以构建可执行文件时却失败了。只要这个可执行文件不访问插件全局变量(如 jpeg_instance
),链接器就看不到连接(他完全忽略了构造函数的副作用)并且不包含代码最终可执行文件。换句话说,JPEG 插件在最终应用中不可用。
这些年来我遇到过几次这样的问题,我总是在网上搜索解决方案。每次,我发现的页面基本上都说这是一个已知问题,我必须忍受它。
但也许 SO 上有人知道如何让它工作?
最佳答案
我不知道这是否是您解决此问题的方法的解决方案,但我们在对象工厂的静态注册方面遇到了类似的问题,在 Visual Studio 中,我们通过声明涉及 __declspec(dllexport) 的类来解决它这是必要的,即使涉及的库不是 dll。但如果没有这个,链接器将忽略未引用的类。
我们工作的注册表解决方案有点不同,不涉及 Stack 分配的对象。我从 CPP 单元中取出零件,这也是我发现 __declspec 方法 iirc 的地方。
[edit] 我们还必须从代码的某些部分#include
注册类的声明。
关于c++ - 静态库中的对象注册,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/873731/