VS2017 和 VS2015 应用程序与 dll 之间的官方二进制不兼容是否准确? [英] Is the official binary incompatibility between VS2017 and VS2015 app vs. dll accurate?

本文介绍了VS2017 和 VS2015 应用程序与 dll 之间的官方二进制不兼容是否准确?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

TL;DR - MS 文档指出 VS2015 和 VS2017 库之间的二进制兼容性是单向,而我认为它必然是双向的.问题在哪里?

TL;DR - The MS docs state that binary compatibility between VS2015 and VS2017 libs is one-way, while I'd assumed it is necessarily two-way. Where's the catch?

首先,背景:

  • Any MSVC++ built libraries are officially binary compatible between VS2015 and VS2017.
  • Specifically, you can use your VS2015 C++ app with the MSVCRT140 version from 2017. (VCRedist backwards compat)
  • The official documentation site states a confusing restriction.

背景/相关问题:

我发现的令人困惑的限制是:

The confusing restriction I find is:

此规则有两个例外.在这些情况下无法保证二进制兼容性:

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

...

使用使用版本高于用于编译和链接应用程序的工具集的工具集构建的库时.例如,使用编译器版本 19.12 编译和链接的程序可以使用使用 19.0 到 19.12 编译的库.

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.

恕我直言,这个警告在技术上既草率又令人困惑.技术原因是什么?

This caveat is, IMHO, both technically sloppy and confusing. What would the technical reason be for that?

我说它是草率的,因为它不完整,因为可执行文件和 DLL 之间的接口非常对称,但这个项目符号只涵盖应用程序".

I say it's sloppy because it is incomplete, because the interface between an executable and a DLL is pretty syymetric, but this bullet only covers "the application".

具体而言,并且假设所有模块都是针对动态 CRT 版本构建的,并且此动态 CRT 版本是可用的最新版本,我看到以下组合存在二进制兼容性问题:

Specifially, and assuming all modules are built against the dynamic CRT version and this dynamic CRT version is the newest version available, I see the following combinations where binary compat is an issue:

  • my_2017.exe <->my_2015.dll -- 貌似支持
  • my_2015.exe <->my_2017.dll--似乎不受支持
  • my_2017.exe <->my_2015.dll <->my_2017_x.dll -- 现在怎么办,btw DLL 支持的方向"是什么?
  • my_2017.exe <-> my_2015.dll -- seemingly supported
  • my_2015.exe <-> my_2017.dll-- seemingly unsupported
  • my_2017.exe <-> my_2015.dll <-> my_2017_x.dll -- what now, in which "direction" is this supported btw DLLs?

由于二进制兼容 - 纯粹从二进制/接口的角度来看 - 必须双向运行,我不太明白我们会突然在这里遇到不兼容的地方:API 调用可以双向(回调等),对象移动"双向,甚至 DLL 加载的顺序也可以混合.

Since binary compat - purely from the binary/interface perspective - must run both ways, I don't quite see where we suddenly could get an incompatibility here: API calls can go both ways (callbacks etc.), objects "move" both ways, even the order of DLL loading can be mixed.

恕我直言,这是很重要的一点,因为这意味着二进制兼容性如上所述严重受限的:

This is an important point IMHO, as it means the binary compatibility as stated is severly limited:

  • 如果我的应用程序想要使用任何 VC14* 编译库,我官方"仍然必须确保我的应用程序是使用最新版本"构建的.
  • 另一方面,如果不构建应用程序",但有一个 DLL,我似乎可以使用任何其他 VC14* DLL 并兼容?
  • 使用 VCRedist,我们完全遇到了看似不支持的情况,即我们被允许使用 VC2017 库(在本例中为 CRT)来自 2015 年的应用!
  • If my application want's to consume any VC14* compiled library, I "officially" still must make sure that my application is built with the "newest version".
  • On the other hand, if don't build an "application", but have a DLL, I can seemingly consume any other VC14* DLL and be compatible?
  • With the VCRedist, we have exactly the case that is seemingly unsupported, namely we are allowed to consume a VC2017 library (CRT in this case) from a 2015 app!

那么,为什么(!)在其方式上受到限制,以及它与 dll 间依赖关系以及倒置(!)CRT-dll 版本要求有何关系.

So, why(!) is this limited in the way it is, and how does it relate to inter-dll dependencies and also the inverted(!) CRT-dll version requirement.

推荐答案

Microsoft 已经更新了他们的文档,即当前版本 https://docs.microsoft.com/en-us/cpp/porting/binary-compat-2015-2017 内容:

Microsoft has since updated their docs, the relevant section of the current version of https://docs.microsoft.com/en-us/cpp/porting/binary-compat-2015-2017 reads:

...

当您混合使用不同支持版本的 MSVC 工具集构建的二进制文件时,运行应用程序的 Visual C++ 可再发行组件不能较旧比使用的任何工具集版本构建您的应用或它使用的任何库.

When you mix binaries built with different supported versions of the MSVC toolset, the Visual C++ redistributable that your application runs on cannot be older than any of the toolset versions used to build your app or any libraries it consumes.

差异位于 https://github.com/MicrosoftDocs/cpp-docs/commit/a505dccfb31eb49c2ffece4dabd24a0a61b1fcb3#diff-d488b4c71be450b2a39cdce495c229bf

这并没有直接的 GitHub/MS-Docs 问题,但这个限制更有意义:它只是谈论 可再发行 的兼容性要求,并且需要 VC 运行时版本至少与正在使用的最新模块一样最新.

There is no direct GitHub/MS-Docs issue for this, but this limitation makes a lot more sense: It just talks about the compatibility requirements of the redistributable, and requiring a VC runtime version that is at least as current as the newest module in use.

这当然是有道理的,因为这不仅仅是纯粹的二进制兼容性.

This, of course, can make sense, as this is not only pure binary compatibility.

当然,我在问题中所说的仍然有效:任何(旧)VS2015 应用程序都必须与(新)VS2019 可再发行产品兼容,所以我猜 VCRedist-VC14.0 曾经暴露的所有界面表面应该是二进制兼容.

Of course, what I said in the question still is valid: Any (old) VS2015 application must be compatible with the (new) VS2019 redistributable, so I guess all the interface surface that VCRedist-VC14.0 ever exposed should be binary compatible.

这篇关于VS2017 和 VS2015 应用程序与 dll 之间的官方二进制不兼容是否准确?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆