C++ MSC_VER mismatch with Third Party library

2019-08-20 06:24发布

问题:

I have a project which is to be upgraded to VS2013. One of the libraries I am linking with is third party, so I am unable to 're-compile' it as it is supplied as a single file by the vendor.

Is there any way to use this library in my newly updated project ?

Obviously if I attempt a link currently I get MSC_VER mismatch messages v1600 does not match v1800 etc etc

回答1:

C++ does not specify an Application Binary Interface (ABI), so it's implementation dependent. As such, static libraries built by one version of any compiler are not necessarily compatible with any other. In particular, Microsoft Visual C++ does not guarantee binary compatibility between major revisions (VS 2012 to VS 2013 for example). The #pragma detect_mismatch machinery was added back in Visual C++ 2010 to make this an explicit link error LNK2038 instead of silently linking and ultimately failing at runtime.

For Windows, DLLs typically use a known ABI either via extern "C" or COM interfaces with strict rules to ensure they can be consumed by different compilers. Each DLL links with the C/C++ Runtime it needs, so you can end up with multiple copies of the C/C++ Runtime in one application. You can't use Standard Library stuff like std::vector or std::string as parameters to exported functions because they memory layout of those types can and do change from compiler to compiler, and similarly you have be very careful with inline functions.

The only Windows platform static libraries that are expected to work between major versions contain only C-style data (i.e. UUID.LIB, DXGUID.LIB). You could use C-only functions in a static library but only if they called no C/C++ Runtime functions.

The one exception to this rule is that VS 2017 has specifically been made binary compatible with VS 2015 Update 3 and they share the same C/C++ Runtime (although VS 2017 version is newer). So if you have a static library built with VS 2015 Update 3, you can link it with code built with VS 2017 as long as you are ultimately linking it against the VS 2017 version of the C/C++ Runtime.

In fact, the experience with this effort suggests that you shouldn't use _MSC_VER as a variable with #pragma detect_mismatch because it can bite you as it did here. VS 2017 changed to explicitly version their detect_mismatch stamps so they could make sure it stayed "1900". They will have to manually change it when the binary-compatibility is broken in a future major update.

See MSDN and this blog post.

TL;DR: You need all your static 3rd party libraries built by VS 2013 to use VS 2013, or you need a DLL designed to be consumed by different versions of the compiler.