如何在动态加载库中实例化静态类



我正在使用一个基于工厂的编译时插件系统,我想移动到更动态。目前,它是基于静态模板化的注册器类,其中构造函数将类注册到工厂。例如

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开始。

最新更新