用VC10编译的C ++库(sp1)可以用VC11编译的代码链接吗?

时间:2012-04-03 15:04:03

标签: c++ visual-c++ compiler-construction linker

这个问题说明了一切。

据我所知,VC11目前仅处于测试阶段,但我要问的是:

  1. 尝试使用vc10
  2. 编译的封闭源(如果可能的话,广泛使用)链接的经验
  3. Microsoft的规范明确表示如果是或否vc11将能够与vc10库链接。
  4. 我只是谈论C ++案例。

4 个答案:

答案 0 :(得分:3)

对于动态关联的情况,您可能需要阅读this answer

关于静态链接,我认为你不能安全地将用VCx编写的C ++库与用VCy编译的代码链接起来。例如,STL容器实现从版本更改为版本(甚至在同一版本中,调试和发布模式之间以及_HAS_ITERATOR_DEBUGGING等设置也会发生变化。)

Quoting VC++ STL maintainer

  

STL永远不会保证二进制兼容性   不同主要版本之间。我们用链接器强制执行此操作   混合使用的目标文件/静态库时出错   不同的主要版本都是VC10 + [...]

答案 1 :(得分:1)

对于动态库,应该没有问题,因为它们遵循明确定义的ABI。您可以随时从任何编译器链接到dll。

静态库比较棘手。据我所知,微软从未保证交叉编译器的兼容性。特别是,已知链接时代码生成等功能会破坏早期版本之间的兼容性。 .lib文件没有像DLL这样的明确定义的格式。

它可能有用,因为除非必须,否则微软很少会破坏兼容性,但据我所知,它不能保证。

当然,如果DLL暴露的实际功能和类型不匹配,你就会遇到问题。

在VC11中,几乎所有标准库数据结构的大小都已更改(Microsoft 最终采用空基类优化,有效地减少了使用默认分配器的所有容器的大小。),所以试图将用VC10编译的DLL中的std::string传递给VC11编译的模块肯定会破坏。

答案 2 :(得分:1)

这是一个响亮的否定! VS的每个主要版本都有一个新版本的动态CRT,名称为VS2008的msvcr90.dll,VS2010的msvcr100.dll,VS11的msvcr110.dll。

当您从导出的函数返回类似std :: string的C ++对象时,使用动态CRT(/ MD编译选项)很重要,否则返回需要被客户端代码删除的任何指针。这只能在客户端代码使用与DLL完全相同的CRT版本时才能正常工作。隐含的是,当这些代码块各自对msvcrXXX.dll版本有自己的依赖时,情况并非如此,它们将不可避免地具有不兼容的CRT版本,这些版本不共享相同的堆分配器。

您可以编写可以安全使用任何CRT版本的DLL,但这需要仔细制作API,以便不存在这些依赖项。 COM自动化模型就是一个例子。

答案 3 :(得分:0)

我认为他们之间没有任何不相容的理由。无论您使用哪种C ++编译器,只要它们遵循格式规范就会生成LIB文件。如果您对格式的详细信息感兴趣,可以查看this question