防止静态库中的模板实例化

时间:2016-11-01 02:05:05

标签: c++ templates static-libraries ace opendds

我正在尝试构建一个静态库,其中包含从各种IDL文件中获取的DDS主题的定义。我使用OpenDDS作为我的中间件。

当我创建一个包含sequence<long>的IDL文件时,将其编译到我的静态库中,然后将静态库链接到我的应用程序,我得到涉及多个符号定义的链接器错误:

Error   LNK2005 "public: void __cdecl TAO::unbounded_value_sequence<int>::length(unsigned int)" (?length@?$unbounded_value_sequence@H@TAO@@QEAAXI@Z) already defined in TAO.lib(TAO.dll)    

我相信这是因为我的静态库包含unbounded_value_sequence的模板实例化,我的应用程序也包含实例化。它似乎来自ACE TAO,由OpenDDS使用。

我正在寻找一种方法来避免在我的静态库中完全实例化模板,以便它们可以在链接在一起时使用应用程序中的定义。我尝试添加以下内容:

extern template class TAO::unbounded_value_sequence<int>;

这产生了以下错误:

Error   C2961   'TAO::unbounded_value_sequence<CORBA::Long>': inconsistent explicit instantiations, a previous explicit instantiation did not specify '__declspec(dllimport)'

我试图找到该实例化,但它不在我的代码中。它可能在ACE本身内。

如果我在一个项目中构建所有内容,则不会出现问题,但这不是一个理想的解决方案。

1 个答案:

答案 0 :(得分:1)

使用extern模板需要做些什么有点不同。实际上,声明extern模板将阻止它的实例化。但是你需要一个实例某处。那个地方通常是一个带有你要编译的模板名称的cpp。

unbounded_value_sequence.h:

// template struct here

extern template class TAO::unbounded_value_sequence<int>;
extern template class TAO::unbounded_value_sequence<long>;
// and every other instantiation you want to be in your static library

unbounded_value_sequence.cpp:

#include "unbounded_value_sequence.h"

// Here you compile them one time.
template class TAO::unbounded_value_sequence<int>;
template class TAO::unbounded_value_sequence<long>;
// and every other instantiation you want to be in your static library

这将使您的模板仅在您的库中实例化一次。编译器将生成包含模板实例的unbounded_value_sequence目标文件。它们只存在于那里。

如果您希望图书馆的用户使用他们的模板类,请不要忘记您仍然需要在标题中显示模板实现。