【问题标题】:VS2012 compatibility with VS2019VS2012 与 VS2019 的兼容性
【发布时间】:2021-04-22 21:37:38
【问题描述】:

所以,我知道 Microsoft 增强了他们的工具集,使得使用 VS2015、VS2017 和 VS2019 构建的应用程序和库之间存在兼容性。

但是,我认为这种组合会失败: 使用 VS2012 (VC11) 的工具集构建的 C++ 应用程序 (.exe),在运行时与 包含使用 VS2019 工具集构建的 C++ 的共享库 (.dll)

但是,我们已经看到这种组合“似乎”有效。

我预计这种组合会失败,但无法解释它的成功。 有人对此有任何想法吗?

【问题讨论】:

  • 也许你对 gcc 编译的 dll 感到困惑

标签: c++ visual-studio-2012 compatibility


【解决方案1】:

Microsoft Docs 中涵盖的 VS 2015 Update 3、VS 2017 和 VS 2019 之间的“二进制兼容性”专门围绕标准 C++ 库和静态库链接。历史上不同代的工具集将无法链接或在运行时崩溃。为避免崩溃,VS 添加了这些符号,以便您在链接时收到错误:

error LNK2038: mismatch detected for '_MSC_VER': value '1600' doesn't match value '1700' in CppFile1.obj

VS 2015 Update 3、VS 2017 和 VS 2019 都使用“1900”作为链接标记,因为它们经过设计和测试可以在混合时工作。当然,重要的是要注意最终链接预计将针对较新的 CRT 库和链接器(即它仅向前兼容)。只有在使用 C++ 头文件时才会拉入链接标记,而不是 C 头文件或 Win32 系统头文件。

例如,如果您有一个 C++ 库,该库具有在类实现中对 std::vector 起作用的内联函数,并且该类的其余部分托管在 DLL 中,从历史上看,如果您使用不同的工具集构建,这将失败因为std::vector 的实现将使用不同的二进制布局等。这是在工具集之间拥有这种“二进制兼容性”策略的关键价值,因此更容易使用最新的工具集并保留大多数现有的 3rd 方库和工具。

通过导入库的 C ABI 始终可以跨编译器版本工作。这在很大程度上是 Win32 API 和 COM API 托管在 DLL 中并使用 C ABI 的原因。否则,编译器工具集的每个版本都需要一组新的操作系统库。理论上,您可以使用古老的 Platform SDK 之一中提供的库成功地将程序与 VS 2019 链接。

所以这真的取决于你的 exe 正在使用什么。如果它只是使用 C API、外部“C”链接和/或 Win32 API,那么无论您使用什么组合,它都可以正常工作。

TL;DR: 使用 C ABI 的动态链接库可以跨工具集工作。静态库或带有 C++ ABI 的库只能在特定场景下跨工具集工作。

这里还有一个警告:整个程序优化/链接时代码生成静态库在工具集之间不兼容。

【讨论】:

  • 我在我原来的问题中添加了一些信息,具体说明应用程序中的代码和 DLL 中的代码都是用 C++ 编写的。
  • 过去,使用 VS2008 构建的同一应用程序在尝试加载使用 VS2012 构建的 DLL 时将无法运行;它会崩溃。因此我们不确定为什么 VS2012/VS2019 组合有效
  • VS 2005 和 VS2008 使用 Fusion 并行清单来尝试主动管理 CRT 服务,这充满了问题和怪癖。
  • 那么,你是说我应该接受它正在工作并为此感到高兴吗? :)
  • 差不多。哦,不要指望它每次都这样工作:)
猜你喜欢
  • 2012-11-09
  • 2013-01-03
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2020-01-10
  • 2013-01-22
  • 2020-05-26
  • 2018-11-09
相关资源
最近更新 更多