关于“ Visual Studio 2015和Visual Studio 2017之间的二进制兼容性”的问题

时间:2018-11-07 07:19:56

标签: c++ visual-studio-2015 visual-studio-2017 binary-compatibility

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

  

1)使用/ GL编译器开关编译静态库或目标文件时。

     

2)在使用由工具集构建的库时,该工具集的版本大于用于编译和链接应用程序的工具集。例如,被编译并与编译器版本19.12链接的程序可能会消耗从19.12到19.12为止编译的库。此外,二进制兼容性仅在Visual Studio 2015和Visual Studio 2017之间存在;其他情况下,二进制兼容性不存在。不支持将19.x程序与Visual Studio 2013或更早版本生产的库链接。

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

让我们更具体一些。提供了一个文件夹,其中包含一个自定义exe,一个自定义dll和vc_toolset dll(v140或v141)的一部分。自定义exe和自定义dll都动态链接到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工具集dlls

基于情况1,此外,工具集dll被vs2017随附的较新版本代替。

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

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

基于情况1,使用vs2017重建了自定义dll。然后有两种选择:

a)仅替换dll,并且不会使用新的dll的导入lib重建exe。

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

根据上述链接的异常2,在a)和b)情况下不能保证二进制兼容性。但为什么 ?自定义dll的所有接口和依赖项都没有更改,并且不依赖v141的新功能。

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

基于情况3,此外,工具集dll被vs2017随附的较新版本取代。

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

基于案例1,使用vs2017重新构建了自定义exe,并与先前由vs2015构建的自定义dll的导入库链接

根据上述链接,我认为在这种情况下可以保证二进制兼容性。

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

基于情况5,此外,工具集dll被vs2017随附的较新版本代替。 如果情况5和情况2可以得到保证,那么我认为在这种情况下也可以得到保证。

我的理解正确吗?

2 个答案:

答案 0 :(得分:1)

自从您明确调用

  

... CRT DLLs ...

我将回答这一部分:

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

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

在VS 2017 vs.2015中,所有CRT DLL都具有相同的文件名,即msvcp140.dllvcruntime140.dll,没有141文件! (因此,项目符号点6不存在。)

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


鉴于此,我会根据您的问题简单地不做案例35(关于CRT):始终部署最新您的组件所依赖的MS CRT。

甚至找到了blog entry wrt. this(2017/03/07):

  

... VCRedist仅向后兼容,因此您需要随应用重新分发VS 2017中提供的最新VCRedist 140。 ...


关于第3点和第4点的问题2015.exe <-> 2017.dll,我创建了一个新问题:Is the official binary incompatibility between VS2017 and VS2015 app vs. dll accurate?,因为这确实很奇怪,恕我直言。

答案 1 :(得分:0)

您引用的文章的重点是Microsoft INCREASED 可能在MSVS 2015和MSVS 2017二进制文件之间实现兼容性。

它仅列出两个例外:

  

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

     

Visual Studio 2015和Visual Studio 2017之间的C ++二进制兼容性

     

在Visual Studio的早期版本中,   目标文件(OBJ),静态库(LIB),动态库   (DLL)和通过使用不同版本的   不能保证编译器工具集和运行时库。

     

这已在Visual Studio 2017中更改。在Visual Studio 2015和Visual中   Studio 2017,C ++工具集的主要编号为14(Visual v140   Studio 2015和Visual Studio 2017的v141)。这反映了事实   运行时库和应用程序都使用   这两个版本的编译器在大多数情况下都是二进制文件   兼容。

     

例如,这意味着如果您在Visual中拥有DLL,   Studio 2015,您无需重新编译即可使用它   从使用Visual Studio 2017构建的应用程序中获取。

     

此规则有两个例外。二进制兼容性不是   在这些情况下可以保证:

     
      
  1. 使用/ GL编译器开关编译静态库或目标文件时。

  2.   
  3. 在使用由工具集构建的库时,该工具集的版本大于用于编译和链接应用程序的工具集。

  4.