关于 "Binary Compatibility between Visual Studio 2015 and Visual Studio 2017" 的问题

Questions about "Binary Compatibility between Visual Studio 2015 and Visual Studio 2017"

https://docs.microsoft.com/en-us/cpp/porting/binary-compat-2015-2017?view=vs-2017 表示 Visual Studio 2015 和 Visual Studio 2017 之间的 C++ 二进制兼容性得到保证,除了:

1)When static libraries or object files are compiled with the /GL compiler switch.

2)When consuming libraries built with a toolset whose version is greater than the toolset used to compile and link the application. For example, a program that is compiled and linked with compiler version 19.12 can consume libraries that are compiled with 19.0 up through 19.12. Also, binary compatibility only exists between Visual Studio 2015 and Visual Studio 2017; linking 19.x programs with libraries produced by Visual Studio 2013 or earlier is not supported.

异常 2 让我感到困惑。为什么在这种情况下不能保证二进制兼容性?

让我们更具体一点。提供了一个包含自定义 exe、自定义 dll 和部分 vc_toolset dll(v140 或 v141)的文件夹。自定义 exe 和自定义 dll 都被 link 动态编辑为 vc_toolset dll 的一部分,其中包括 CRT dll、msvcp140.dll、vcruntime140.dll。此外,/GL 选项未启用。

我在下面列出了几种组合。我想知道每个人的二进制兼容性。

1)vs2015构建的exe + vs2015构建的dll + vs2015的v140工具集dll

我觉得这样可以保证二进制兼容性

2)vs2015构建的exe + vs2015构建的dll + vs2017的v141工具集dll

基于案例 1,此外,工具集 dll 已替换为 vs2017 附带的更新版本。

另外,我认为这种情况下可以保证二进制兼容性

3)由 vs2015 + dll 构建的 exe 由 vs2017 重建 + vs2015 的 v140 工具集 dll

基于案例1,使用vs2017重建自定义dll。然后有两个选择:

a) 只需替换 dll,不会使用新 dll 的导入库重建 exe

b) 替换 dll 并使用新 dll 的导入库重建 exe。

根据上面link的例外2,a)和b)的情况不能保证二进制兼容性。但为什么 ?自定义dll的所有接口和依赖都没有改变,不依赖v141的新特性。

4) 由 vs2015 构建的 exe + dll 由 vs2017 重建 + vs2017 的 v141 工具集 dll

基于案例 3,此外,工具集 dll 已替换为 vs2017 附带的更新版本。

5)exe 由 vs2017 重建 + 由 vs2015 构建的 dll + vs2015 的 v140 工具集 dll

基于案例1,使用vs2017重建了自定义exe,并link使用之前由vs2015构建的自定义dll的导入库

根据上面link,我觉得这种情况下可以保证二进制兼容性

6)exe 由 vs2017 重建 + 由 vs2015 构建的 dll + vs2017 的 v141 工具集 dll

基于案例 5,此外,工具集 dll 已替换为 vs2017 附带的更新版本。 如果case 5和case 2可以保证,我觉得这个case也可以保证

我的理解正确吗?

您引用的文章的主要观点是,Microsoft 增加 MSVS 2015 和 MSVS 2017 二进制文件之间兼容的可能性。

它只列出了两个例外:

https://docs.microsoft.com/en-us/cpp/porting/binary-compat-2015-2017?view=vs-2017

C++ Binary Compatibility between Visual Studio 2015 and Visual Studio 2017

In previous versions of Visual Studio, binary compatibility between object files (OBJs), static libraries (LIBs), dynamic libraries (DLLs), and executables (EXEs) built by using different versions of the compiler toolset and runtime libraries was not guaranteed.

This has changed in Visual Studio 2017. In Visual Studio 2015 and Visual Studio 2017, the C++ toolset major number is 14 (v140 for Visual Studio 2015 and v141 for Visual Studio 2017). This reflects the fact that both the runtime libraries and the applications compiled with either version of the compiler are--for the most part--binary compatible.

This means, for example, that if you have a DLL in Visual Studio 2015, you don't have to recompile it in order to consume it from an application that is built with Visual Studio 2017.

There are two exceptions to this rule. Binary compatibility is not guaranteed in these cases:

  1. When static libraries or object files are compiled with the /GL compiler switch.

  2. When consuming libraries built with a toolset whose version is greater than the toolset used to compile and link the application.

因为你明确地调用了

... CRT DLLs ...

我会回答那部分:

VS2017 CRT 和 VS2015 CRT 之间的向后兼容性是 100% 保证的! (当然是模数 MS 错误。)

我怎么说呢? MSVC CRT 的默认部署方法是将所有 CRT 文件部署到 System32,因此大多数应用程序将使用一 (1) 个全局 CRT DLL 集。 (至少 AFAIKT,许多应用程序以 DLL 形式使用 MS CRT,但不将所有 CRT DLL 捆绑在其应用程序目录中。)

对于 VS 2017 和 2015,所有 CRT DLL 都具有 相同的文件名,即 msvcp140.dllvcruntime140.dll,没有 [=13] =] 文件! (所以要点 6 不存在。)

因此给定的 Windows 系统最多可以拥有一组全局 CRT140 文件,并且由于没有应用程序控制它,因此新版本的 CRT140 必须向后兼容针对旧版本构建的应用程序。


鉴于此,我只是 不做 案例 35(关于 CRT)从你的问题:始终部署 最新的 您的组件所依赖的 MS CRT。

偶发现一个 blog entry wrt. this (2017/03/07):

... The VCRedist is only backward compatible, so you will need to redistribute the latest VCRedist 140 available in VS 2017 with your app. ...


关于要点 3 和 4 的情况 2015.exe <-> 2017.dll我提出了一个新问题: 因为这真的很奇怪,恕我直言。