我正在使用一个基于工厂的编译时插件系统,我想移动到更动态。目前,它是基于静态模板化的注册器类,其中构造函数将类注册到工厂。例如
template <class T>
SingleModuleRegistrar<T>::SingleModuleRegistrar(ModuleDesc description={ T::factoryName(), T::category }) : _name(description.moduleName)
{
ModuleFactory& factory = ModuleFactory::Instance();
factory.Register(this, description);
}
,然后在DefaultPlugin
类的头中
static SingleModuleRegistrar<DefaultPlugin> DefaultPluginRegistrar;
在静态库中构建时,DefaultPlugin
向工厂注册并可供使用。现在我想将静态库移动到dll中,这样我就可以动态地向工厂添加新的插件。我可以加载dll没有问题,但静态变量似乎没有得到安装。如果不是,我如何触发静态DefaultPluginRegistrar
的实例化?
我可以想到一些变通方法,例如添加一个函数来在库中注册插件并调用它,但我认为如果我能尽可能地接近原始代码,那就太好了。另外,我想了解在加载过程中静态变量实例化发生了什么。
编辑:我想我应该添加一些关于结构的细节。目前DefaultPlugin
注册是在一个库的头是静态链接到.dll。它也在一个命名空间中。
MyPlugin.dll
|_ MyStaticLibrary.lib
|_DefaultPlugin.h
SomeNamespace {
class DefaultPlugin : public IPlugin
{
public:
DefaultPlugin();
//etc.
};
// registration
static SingleModuleRegistrar<DefaultPlugin> DefaultPluginRegistrar;
}
|_ SomeOtherStaticLibrary.lib
我也试过删除静态声明并导出符号,但无济于事
__declspec(dllexport) SingleModuleRegistrar<DefaultPlugin> DefaultPluginRegistrar;
OK:超级捂脸时间。我一直在将我的代码结构重新组织成如此漂亮的独立库,以至于我实际上没有在dll代码的任何地方包含包含静态插件声明的头文件!
我将把这个问题留在这里,因为我发现这是一个非常不寻常的配置,它可能会帮助一些人知道它可以工作。
注意到在MS运行时中,静态是在initterm.cpp
中的_initterm
中初始化的,从dll_main_crt_process_attach
开始。