我在尝试隐式地从静态库导入符号时提交了一个问题。
让我用简单的代码来安排问题:
我有3个项目: - 一个定义注册表类的静态插件处理程序项目,它在另外两个项目中链接 - 一个静态插件项目 - 一个具有插件处理程序和“静态加载”插件的最终项目。
首先,静态插件处理程序项目:
struct PluginType
{
virtual void doMyStuff() = 0 ;
};
typedef PluginType* (*PluginCreator)();
struct Registry
{
std::map<std::string, PluginCreator> _item_list;
static Registry& instance()
{
static Registry singleton;
return singleton;
}
static PluginType* create(std::string const& name)
{
// call the creator function that returns an PluginType*
return instance()[name]();
}
};
struct RecordInRegistry
{
RecordInRegistry(std::string const& key, PluginCreator new_item_creator)
{
Registry::instance()._item_list[key] = new_item_creator;
}
};
现在,一个静态插件项目
struct ADerivedItem : public PluginType
{
virtual void doMyStuff() override
{
//some really interesting stuffs
}
static PluginType* create() { return new ADerivedItem() ; }
}
export "C" const RecordInRegistry i_record_derived_item_class("derived_item", &ADerivedItem::create);
然后,我使用插件的最终项目。这个项目链接了另外两个项目!
int main()
{
PluginType* my_instance = Registry::create("derived_item");
return 0;
}
我希望通过链接静态库插件我能够注册我的静态插件 到项目。
它几乎奏效了!我得到的唯一问题是来自静态的符号“i_record_derived_item_class” 插件未在最终项目中显式使用,因此不会从静态插件lib中导入此符号!
我在visual studio上工作,我发现了一个简单的修复,包括强制符号导入,类似于 / INCLUDE:i_record_derived_item_class,一切正常。
我想知道你是否看到了解决这个问题的方法,我希望能够添加这种静态 通过链接来插入,而不必添加任何超过/LINK:myStaticPlugin.lib
有什么想法吗?
此外,避免使用特定于MSVC的解决方案真的很不错。
提前致谢!
答案 0 :(得分:0)
问题是库中的符号仅在需要时使用。 n4659草案在5.2翻译阶段说[lex.phases]:
- 解析所有外部实体引用。库组件链接以满足外部引用 到当前翻译中未定义的实体。
醇>
由于您当前的源没有i_record_derived_item_class
的外部引用,也没有类ADerivedItem
的外部引用,默认情况下不会从插件项目中加载任何内容。更糟糕的是,即使插件处理程序模块也没有引用,因此您需要声明对构建系统本身的未定义引用,无论是MSVC还是其他任何内容。
或者,您可以将包含外部引用的最小翻译单元(表示.cpp或.o文件)链接到i_record_derived_item_class
,以强制从库中进行解析。