C ++ MSC_VER与第三方库不匹配 [英] C++ MSC_VER mismatch with Third Party library

查看:109
本文介绍了C ++ MSC_VER与第三方库不匹配的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一个要升级到VS2013的项目.我要链接的库之一是第三方,因此我无法对其进行重新编译",因为供应商将其作为单个文件提供.

在我最新更新的项目中可以使用此库吗?

很明显,如果我当前尝试链接,则会收到MSC_VER不匹配消息v1600与v1800不匹配等信息

解决方案

C ++未指定应用程序二进制接口(ABI),因此取决于实现.这样,由任何编译器的一个版本构建的静态库不一定与任何其他版本兼容.特别是,Microsoft Visual C ++不保证主要版本之间的二进制兼容性(例如,VS 2012至VS 2013).在Visual C ++ 2010中又添加了#pragma detect_mismatch机制,以使其成为显式链接错误LNK2038,而不是无提示链接并最终在运行时失败.

对于Windows,DLL通常通过严格的规则通过extern "C"或COM接口使用已知的ABI,以确保它们可以被不同的编译器使用.每个DLL都与所需的C/C ++运行时链接,因此最终可以在一个应用程序中获得C/C ++运行时的多个副本.您不能使用std::vectorstd::string之类的标准库作为导出函数的参数,因为它们的内存布局可以并且确实会在编译器之间发生变化,并且类似地,您对内联函数也要非常小心.

唯一预期在主要版本之间工作的Windows平台静态库仅包含C样式数据(即UUID.LIBDXGUID.LIB).您可以在静态库中使用仅C函数,但前提是它们不调用C/C ++运行时函数.

此规则的一个例外是,VS 2017特别是与VS 2015 Update 3二进制兼容,并且它们共享相同的C/C ++运行时(尽管VS 2017版本较新).因此,如果您具有使用VS 2015 Update 3构建的静态库,则可以 将其与使用VS 2017构建的代码链接,只要最终将其与VS 2017版本的C/C ++运行时链接即可

实际上,这种尝试的经验表明您不应该将_MSC_VER用作#pragma detect_mismatch的变量,因为它可能像在这里一样咬住您. VS 2017更改为显式版本其detect_mismatch戳记,以便他们确保其保持在"1900".当二进制兼容性在以后的重大更新中被破坏时,他们将不得不手动更改它.

请参见 MSDN 此博客文章.

TL; DR::需要使用VS 2013构建的所有静态第三方库才能使用VS 2013,或者需要设计为供不同版本的编译器使用的DLL.

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

解决方案

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.

这篇关于C ++ MSC_VER与第三方库不匹配的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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