我有一个要升级到VS2013的项目。我链接的其中一个图书馆是第三方,所以我无法重新编译#39;因为它是供应商提供的单个文件。
有没有办法在我新更新的项目中使用这个库?
显然,如果我现在尝试链接,我会收到MSC_VER不匹配消息v1600与v1800等不匹配等
答案 0 :(得分:1)
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 ++ Runtime链接,因此您最终可以在一个应用程序中使用C / C ++ Runtime的多个副本。您不能使用std::vector
或std::string
之类的标准库作为导出函数的参数,因为这些类型的内存布局可以并且确实从编译器更改为编译器,同样您也要非常小心内联函数。
预期在主要版本之间工作的唯一Windows平台静态库仅包含C样式数据(即UUID.LIB
,DXGUID.LIB
)。您可以在静态库中使用仅C函数,但前提是它们不调用C / C ++运行时函数。
此规则的一个例外是VS 2017特别与VS 2015 Update 3二进制兼容,并且它们共享相同的C / C ++运行时(尽管VS 2017版本更新)。因此,如果您有一个使用VS 2015 Update 3构建的静态库,只要您最终将它与VS 2017版本的C / C ++ Runtime链接,就可以将其与使用VS 2017构建的代码链接起来。
事实上,这项工作的经验表明,您不应将
_MSC_VER
用作#pragma detect_mismatch
的变量,因为它可能会像在此处一样咬你。 VS 2017更改为明确标记他们的detect_mismatch
邮票,以便他们可以确保它保持在" 1900"。当在未来的主要更新中破坏二进制兼容性时,他们将不得不手动更改它。
请参阅MSDN和this blog post。
TL; DR:您需要VS 2013构建的所有静态第三方库都使用VS 2013,或者您需要一个设计用于不同版本编译器的DLL。