问题
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?
First, for background:
- 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.
Background / related Questions:
- Is Visual-C++-2017 binary compatible with VC++-2015?
- Questions about "Binary Compatibility between Visual Studio 2015 and Visual Studio 2017"
- Binary compatibility between VS2017 and VS2015
The confusing restriction I find is:
There are two exceptions to this rule. Binary compatibility is not guaranteed in these cases:
...
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?
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".
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
-- seemingly supportedmy_2015.exe <-> my_2017.dll
-- seemingly unsupportedmy_2017.exe <-> my_2015.dll <-> my_2017_x.dll
-- what now, in which "direction" is this supported btw DLLs?
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:
- 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!
Question
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.
回答1:
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:
C++ Binary Compatibility between Visual Studio 2015 and Visual Studio 2019
...
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.
The diff is at https://github.com/MicrosoftDocs/cpp-docs/commit/a505dccfb31eb49c2ffece4dabd24a0a61b1fcb3#diff-d488b4c71be450b2a39cdce495c229bf
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.
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.
来源:https://stackoverflow.com/questions/53187152/is-the-official-binary-incompatibility-between-vs2017-and-vs2015-app-vs-dll-acc