无法导出模板函数
我有一个名为“SimObject”的类:
namespace simBase
{
class __declspec(dllexport) SimObject: public SimSomething
{
public:
template <class T>
void updateParamValue( const std::string& name, T val );
}
}
我有另一个名为“ITerrainDrawable”的类:
namespace simTerrain
{
class __declspec(dllexport) ITerrainDrawable : public simBase::SimObject
{
}
}
这些类位于不同的库中。 SimObject位于simBase中,ITerrainDrawable位于simTerrain库中。即使 ITerrainDrawable 派生自 SimObject 并且我包含了 simBase 库,我也会收到链接错误:
无法解析的外部符号
1>ITerrainDrawable.obj : error LNK2019: unresolved external symbol "public: void __thiscall simBase::SimObject::updateParamValue<float>(class std::basic_string<char,struct std::char_traits<char>,class std::allocator<char> > const &,float)" (??$updateParamValue@M@SimObject@simBase@@QAEXABV?$basic_string@DU?$char_traits@D@std@@V?$allocator@D@2@@std@@M@Z) referenced in function "public: void __thiscall simTerrain::ITerrainDrawable::setTerrainSize(float)" (?setTerrainSize@ITerrainDrawable@simTerrain@@QAEXM@Z)
1>ITerrainDrawable.obj : error LNK2019: unresolved external symbol "public: void __thiscall simBase::SimObject::updateParamValue<class osg::Vec4f>(class std::basic_string<char,struct std::char_traits<char>,class std::allocator<char> > const &,class osg::Vec4f)" (??$updateParamValue@VVec4f@osg@@@SimObject@simBase@@QAEXABV?$basic_string@DU?$char_traits@D@std@@V?$allocator@D@2@@std@@VVec4f@osg@@@Z) referenced in function "public: void __thiscall simTerrain::ITerrainDrawable::setSatelliteTextureBorders(class osg::Vec2f,class osg::Vec2f)" (?setSatelliteTextureBorders@ITerrainDrawable@simTerrain@@QAEXVVec2f@osg@@0@Z)
为什么会出现此错误?
如果我不使用模板函数但我需要它,一切都会正常工作。
如果我将此函数移至 simTerrain 库,它可以正常工作,但我不想使用重复的函数,因为有很多像 simTerrain 这样的库。
I have a class named "SimObject":
namespace simBase
{
class __declspec(dllexport) SimObject: public SimSomething
{
public:
template <class T>
void updateParamValue( const std::string& name, T val );
}
}
I have another class named "ITerrainDrawable":
namespace simTerrain
{
class __declspec(dllexport) ITerrainDrawable : public simBase::SimObject
{
}
}
These classes are in different libraries. SimObject is in simBase, ITerrainDrawable is in simTerrain libraries. Even if ITerrainDrawable is derived from SimObject and I included library of simBase, I get a link error:
unresolved external symbol
1>ITerrainDrawable.obj : error LNK2019: unresolved external symbol "public: void __thiscall simBase::SimObject::updateParamValue<float>(class std::basic_string<char,struct std::char_traits<char>,class std::allocator<char> > const &,float)" (??$updateParamValue@M@SimObject@simBase@@QAEXABV?$basic_string@DU?$char_traits@D@std@@V?$allocator@D@2@@std@@M@Z) referenced in function "public: void __thiscall simTerrain::ITerrainDrawable::setTerrainSize(float)" (?setTerrainSize@ITerrainDrawable@simTerrain@@QAEXM@Z)
1>ITerrainDrawable.obj : error LNK2019: unresolved external symbol "public: void __thiscall simBase::SimObject::updateParamValue<class osg::Vec4f>(class std::basic_string<char,struct std::char_traits<char>,class std::allocator<char> > const &,class osg::Vec4f)" (??$updateParamValue@VVec4f@osg@@@SimObject@simBase@@QAEXABV?$basic_string@DU?$char_traits@D@std@@V?$allocator@D@2@@std@@VVec4f@osg@@@Z) referenced in function "public: void __thiscall simTerrain::ITerrainDrawable::setSatelliteTextureBorders(class osg::Vec2f,class osg::Vec2f)" (?setSatelliteTextureBorders@ITerrainDrawable@simTerrain@@QAEXVVec2f@osg@@0@Z)
Why do I get this error?
Everything works fine if I don't use template function but I need it.
If I move this function to simTerrain library it works fine but I don't want to use duplicate function because there are many libraries like simTerrain.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(5)
C++并不真正支持模板代码的单独编译——你需要将模板的定义放在头文件中。
C++ does not really support the separate compilation of template code - you need to put the definition of the template in a header file.
模板有两种编译模型:
您可以在模板定义时使用导出关键字作为第二个选项。
但我不确定所有编译器都支持它。
There are two compilation model for templates :
You can use export keyword at time of template definition for 2nd option.
But I am not sure that all compiler supports it.
模板类的完整实现必须位于该模板类的标头中。 C++ 的 ANSI/ISO 标准允许使用 export 关键字将实现放入单独的编译单元中,但目前有任何编译器实际上支持此功能。
如需了解更多信息,请阅读此和这个。
The full implementation of a template class must be in that template class's header. The ANSI/ISO standards for C++ allow for a way to put the implementation in a separate compilation unit using the export keyword , but there are currently any compilers that actually support this.
For more information read this and this.
您需要指定(cpp 文件即可)模板专业化。这意味着您需要导出模板参数的所有组合,您将使用:
我在 Visual Studio 2013 中使用它并且它有效。
You need to specify (cpp file is fine) template specialization. It means you need to export all combination of template arguments, you are going to use:
I use this in Visual Studio 2013 and it works.
以下是工作示例:
文件 test.dll 的转储
文件类型:DLL
部分包含 test.dll 的以下导出
Here is the working example:
Dump of file test.dll
File Type: DLL
Section contains the following exports for test.dll