隐式使用静态库中的符号
Implicit use of symbol from a static library
我来提交我在尝试隐式从静态库中导入符号时遇到的问题。
让我用简单的代码来解决问题:
我有 3 个项目:
- 定义注册表 class 的静态插件处理程序项目,它链接在其他两个项目中
- 静态插件项目
- 具有插件处理程序和 "load statically" 插件的最终项目。
首先,静态插件处理程序项目:
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"
插件没有在最终项目中明确使用,因此这个符号不是从静态插件库中导入的!
我在 visual studio 上工作,我发现了一个简单的修复方法,它包括强制导入符号,比如
/INCLUDE:i_record_derived_item_class,一切正常。
我想知道你是否看到了解决这个问题的方法,我想要的是能够添加这种静态
只需链接即可插入,无需添加任何内容 /LINK:myStaticPlugin.lib
有什么想法吗?
此外,避免特定于 MSVC 的解决方案会非常好。
提前致谢!
问题在于库中的符号仅在需要时使用。草案 n4659 在 5.2 翻译阶段说 [lex.phases]:
- All external entity references are resolved. Library components are linked to satisfy external references
to entities not defined in the current translation.
由于您当前的源代码没有对 i_record_derived_item_class
的外部引用,也没有对 class ADerivedItem
的外部引用,因此默认情况下不会从插件项目中加载任何内容。更糟糕的是,即使是插件处理程序模块也没有引用,因此您需要声明对构建系统本身的未定义引用,无论是 MSVC 还是其他任何东西。
或者,您可以 link 包含对 i_record_derived_item_class
的外部引用的最小翻译单元(表示 .cpp 或 .o 文件),以强制从库中解析。
我来提交我在尝试隐式从静态库中导入符号时遇到的问题。
让我用简单的代码来解决问题:
我有 3 个项目: - 定义注册表 class 的静态插件处理程序项目,它链接在其他两个项目中 - 静态插件项目 - 具有插件处理程序和 "load statically" 插件的最终项目。
首先,静态插件处理程序项目:
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" 插件没有在最终项目中明确使用,因此这个符号不是从静态插件库中导入的!
我在 visual studio 上工作,我发现了一个简单的修复方法,它包括强制导入符号,比如 /INCLUDE:i_record_derived_item_class,一切正常。
我想知道你是否看到了解决这个问题的方法,我想要的是能够添加这种静态 只需链接即可插入,无需添加任何内容 /LINK:myStaticPlugin.lib
有什么想法吗?
此外,避免特定于 MSVC 的解决方案会非常好。
提前致谢!
问题在于库中的符号仅在需要时使用。草案 n4659 在 5.2 翻译阶段说 [lex.phases]:
- All external entity references are resolved. Library components are linked to satisfy external references to entities not defined in the current translation.
由于您当前的源代码没有对 i_record_derived_item_class
的外部引用,也没有对 class ADerivedItem
的外部引用,因此默认情况下不会从插件项目中加载任何内容。更糟糕的是,即使是插件处理程序模块也没有引用,因此您需要声明对构建系统本身的未定义引用,无论是 MSVC 还是其他任何东西。
或者,您可以 link 包含对 i_record_derived_item_class
的外部引用的最小翻译单元(表示 .cpp 或 .o 文件),以强制从库中解析。