DLL和完全专业化的模板类

时间:2010-02-17 21:49:05

标签: c++ visual-studio templates linker

环境:Visual Studio 9,没有托管扩展的C ++。

我有一个第三方库,它导出MyClass.h中定义的完全专用的模板类MyClass<42>。它被编译成辅助加载器.lib和.dll文件。 .lib文件包含此特化的编译代码和必要的符号。 MyClass.h看起来像这样:

template<UInt D>
class MyClass {
public:
    MyClass() {...};
    virtual ~MyClass() {};
}

现在我想使用这个库。如果我在Client.cpp中包含MyClass.h然后编译它,我将在Client.obj文件中获得这些符号的第二个副本。我可以通过将该专业化的所有成员定义为“extern”来摆脱这些符号。我的Client.cpp看起来像这样:

#include <ThirdParty/MyClass.h>

extern template class MyClass<42>;
extern template MyClass<42>::MyClass<42>();
extern template MyClass<42>::~MyClass<42>();

void MyFunction(MyClass<42>& obj) {...}

问题是我无法以这种方式摆脱虚拟析构函数。对于虚拟析构函数,我得到了几乎标准的LNK2005错误:

ThirdPartyd.lib(ThirdPartyd.dll) : error LNK2005:
    "public: virtual __thiscall MyClass<42>::~MyClass<42>(void)"
    (??1?$MyClass@$01@@@UAE@XZ) already defined in Client.obj

我该怎么办?

2 个答案:

答案 0 :(得分:4)

似乎对于虚拟方法,有必要同时将它们定义为extern__declspec(dllimport)

extern template __declspec(dllimport) MyClass<42>::~MyClass<42>();

这使我的链接器足够高兴能够正确链接我的代码。

如果某位专家描述了原因,或者至少指出了一些解释此案的文章,我会很高兴。

答案 1 :(得分:1)

我相信Visual Studio在dll中使用模板特化来处理某些stl结构。想到string

我快速查看了头文件,看起来好像正在使用

__declspec(dllimport)

关于一堆专业化的声明。但是,对于全班来说,它似乎并没有这样做。

this discussion开始,听起来可以将整个类声明为已导出,但没有说明如何。

对于不那么完整的答案感到抱歉,但希望这可以帮助您探索其他场所。