visual Can用VC10(sp1)编译的C++库可以通过用VC11编译的代码链接

visual Can C++ libraries compiled with VC10 (sp1) be linked by code compiled with VC11?

本文关键字:编译 可以通过 VC11 代码 链接 C++ Can sp1 visual VC10      更新时间:2023-10-16

这个问题说明了一切。

我知道VC11目前只是测试版,但我要问的是:

  1. 尝试链接使用vc10编译的封闭源代码库(如果可能的话,广泛使用)的经验
  2. 微软的规范明确表示,如果是或否,vc11将能够与vc10库链接

我说的只是C++的情况。

您可能想阅读动态链接的答案。

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

引用VC++STL维护程序:

STL从来没有也永远不会保证二进制兼容性在不同的主要版本之间。我们正在使用链接器强制执行此操作混合使用编译的对象文件/静态库时出错不同的主要版本都是VC10+〔…〕

这是一个响亮的否定!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 Automation模型就是一个例子。

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

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

它可能会起作用,因为除非迫不得已,否则微软很少破坏兼容性,但据我所知,这并不能保证。

当然,如果DLL公开的实际函数和类型不匹配,就会遇到问题。

在VC11中,几乎所有标准库数据结构的大小都发生了变化(Microsoft最终采用了空基类优化,有效地减少了所有使用默认分配器的容器的大小。),因此,试图将std::string从用VC10编译的DLL传递到用VC11编译的模块中肯定会失败。

我看不出它们不兼容的任何原因。无论您使用什么C++编译器,只要LIB文件符合格式规范,就可以生成它们。如果你对格式的细节感兴趣,你可以勾选这个问题。

相关文章: