导出模板代码=危险? (MSVC)

时间:2009-10-16 13:57:42

标签: c++ dll templates linker

正如我在另一个SO问题中所提到的,我遇到了this article。当我通过MSVC7.1编译boost 1.40并弹出几个C4251警告时,问题出现了。

现在,在阅读完这篇文章之后,我想知道:通常不鼓励导出模板代码,例如。

class DLLEXPORT_MACRO AClass
{
public:
   std::vector<int> getVecCopy() { return myVec; }
   ...
}

假设此代码通过MSVC7.1编译为DLL。 虽然从其他MSVC7.1代码引用时此代码不会产生任何错误,但据说在MSVC8代码中引用此DLL会在运行时产生崩溃(内存对齐问题?)。

因为这显然很糟糕......处理模板代码问题的“最佳实践”是什么?

2 个答案:

答案 0 :(得分:6)

这似乎是一个坏主意,因为std :: vector在编译器版本之间有所不同或可能不同。但是,这可能在加载时失败,因为std :: vector的名称修改应该在编译器版本之间有所不同(这是名称修改的基本原理)。

除了购买支持它的编译器之外,这个链接时失败是你不能真正强制执行的开发人员。另一种解决方案是将模板类型完全保留在DLL接口之外。把它们放入私人会员。

请注意,问题并非模板所独有。想象一下,std::string是一个UDT而不是一个typedef,由编译器运行时提供。它仍然可以在编译器版本之间进行更改,当然也可以在编译器供它在DLL接口中仍然无法使用。

由于这些原因,实际的解决方案是0.使用C,1。使用COM或2.确定单个编译器版本。

答案 1 :(得分:0)

不幸的是,实际上没有办法导出模板代码。外部库通常只为任何模板提供源代码。有时他们有模板使用辅助类,这些类不是隐藏专有代码的模板。但基本上没办法做到这一点。