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可以得到保证,那么我认为在这种情况下也可以得到保证。
我的理解正确吗?
答案 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.dll
,vcruntime140.dll
,没有141
文件! (因此,项目符号点6
不存在。)
因此,给定的Windows系统最多可以具有一组全局的CRT140文件,并且由于没有应用程序可以控制此文件,因此,新版本的CRT140必须向后兼容针对旧版本构建的应用程序。
鉴于此,我会根据您的问题简单地不做案例3
和5
(关于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构建的应用程序中获取。
此规则有两个例外。二进制兼容性不是 在这些情况下可以保证:
使用/ GL编译器开关编译静态库或目标文件时。
在使用由工具集构建的库时,该工具集的版本大于用于编译和链接应用程序的工具集。