问题说明了一切。
我知道 VC11 目前仅处于测试阶段,但我要问的是:
我只讨论 C++ 的情况。
您可能想阅读这个答案,了解动态链接的情况。
关于静态链接,我认为你不能安全地将用 VCx 编写的 C++ 库与用 VCy 编译的代码链接起来。例如,STL 容器实现随版本的不同而变化(即使在同一版本中,调试和发布模式之间也存在变化,以及 _HAS_ITERATOR_DEBUGGING 等设置)。
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 自动化模型就是一个例子。
对于动态库来说,应该没有问题,因为它们遵循明确定义的 ABI。您可以随时从任何编译器链接到 dll。
静态库比较棘手。据我所知,微软从未保证这些的交叉编译器兼容性。特别是,诸如链接时代码生成之类的功能已知会破坏早期版本之间的兼容性。 .lib 文件不像 DLL 那样具有单一明确定义的格式。
它可能会起作用,因为微软很少会破坏兼容性,除非他们必须这样做,但据我所知,这并不能得到保证。
当然,如果 DLL 公开的实际函数和类型不匹配,你就会遇到问题。
在VC11中,几乎所有标准库数据结构的大小都发生了变化(微软终于采用了空基类优化,有效地减少了所有使用默认分配器的容器的大小。),因此尝试通过一个
std::string
从 VC10 编译的 DLL 到 VC11 编译的模块肯定会崩溃。
我看不出它们有任何不兼容的理由。无论您使用什么 C++ 编译器,只要 LIB 文件遵循格式规范,就会生成它们。如果您对格式细节感兴趣,可以检查这个问题。