C++ 使用Visual Studio 2019上构建的库时Visual Studio 2015上的链接错误

C++ 使用Visual Studio 2019上构建的库时Visual Studio 2015上的链接错误,c++,windows,visual-studio,visual-studio-2015,linker-errors,C++,Windows,Visual Studio,Visual Studio 2015,Linker Errors,我在VisualStudio2019上编译为静态库(使用平台工具集v142),然后编写了一个链接opencv库的演示程序,一切正常。但当我在Visual Studio 2015(使用平台工具集v140)上编译演示时,它抱怨链接错误: 1>------ Build started: Project: parvati_demo, Configuration: Release Win32 ------ 1>opencv_imgproc342.lib(resize.obj) : error

我在VisualStudio2019上编译为静态库(使用平台工具集v142),然后编写了一个链接opencv库的演示程序,一切正常。但当我在Visual Studio 2015(使用平台工具集v140)上编译演示时,它抱怨链接错误:

1>------ Build started: Project: parvati_demo, Configuration: Release Win32 ------
1>opencv_imgproc342.lib(resize.obj) : error LNK2019: unresolved external symbol ___libm_sse2_sincos_ referenced in function "void __cdecl cv::interpolateLanczos4(float,float *)" (?interpolateLanczos4@cv@@YAXMPAM@Z)
1>E:\CPPCode\projects\parvati_release1\build32\Release\parvati_demo.exe : fatal error LNK1120: 1 unresolved externals
2>------ Skipped Build: Project: ALL_BUILD, Configuration: Release Win32 ------
2>Project not selected to build for this solution configuration 
========== Build: 0 succeeded, 1 failed, 1 up-to-date, 1 skipped ==========
据此,;整个Visual Studio 2015/17/19确保了二进制兼容性:
我发现函数
cv::interpolateLanczos4
的定义如下

static inline void插值函数Czos4(浮点x,浮点*系数)
{
静态常数双s45=0.70710678118654752440084436210485;
静态常数双cs[][2]=
{1,0}、{-s45,-s45}、{0,1}、{s45,-s45}、{-1,0}、{s45,s45}、{0,-1}、{-s45,s45};
if(x

其中使用了
std::sin()
std::cos()
,它们在
corecrt\u math.h
中声明。所以,我猜丢失的符号与
libm
xxxcrt.lib
有关。最后,我在Windows10SDK中找到了一个
ucrt.lib
,但它也不起作用。谁能帮帮我?

你误解了微软解释的二进制兼容性的范围。在编译器版本之间兼容的是一个最终的可执行文件(和相关的DLL)和任何版本的C++运行时。也就是说,您可以用VS2019编译应用程序,并使用VS2017/15附带的C++运行库可重分发包。这是您只在使用时才关心的事情。在实践中,这意味着,如果由于某种原因,您使用VS201/V140工具集编译一些可执行文件,并且使用VS2017/V141工具集编译,则只需要用户安装单个C++运行时可重分发。如果您不控制系统上C++运行时的确切版本(这是在某些嵌入式系统中,接受第三方插件必须分布为DLL,不能安装其他资产)的话,这是一个巨大的优势。 但是,构成最终可执行文件的所有对象文件仍然需要使用相同的编译器主版本进行编译。如果使用,甚至需要有匹配的次要编译器版本。通常,对于C++应用程序,强烈建议确保组成最终二进制(包括关联DLL)的所有翻译单元都用完全相同的编译器编译。 编辑: 以下是整个程序优化文档中的一段引文,它强调了一个事实,即在某些情况下,链接使用不同VS版本编译的库可能不起作用:

当前版本中用/GL生成的文件格式可能不会被VisualC++的后续版本读取。您不应该将包含./OL文件的.LIB文件发送到/gl中,除非您愿意为.VisualC++的所有版本提供.LIB文件的拷贝。您希望用户现在和将来使用。


您误解了Microsoft解释的二进制兼容性的范围。在编译器版本之间兼容的是一个最终的可执行文件(和相关的DLL)和任何版本的C++运行时。也就是说,您可以用VS2019编译应用程序,并使用VS2017/15附带的C++运行库可重分发包。这是您只在使用时才关心的事情。在实践中,这意味着,如果由于某种原因,您使用VS201/V140工具集编译一些可执行文件,并且使用VS2017/V141工具集编译,则只需要用户安装单个C++运行时可重分发。如果您不控制系统上C++运行时的确切版本(这是在某些嵌入式系统中,接受第三方插件必须分布为DLL,不能安装其他资产)的话,这是一个巨大的优势。 但是,构成最终可执行文件的所有对象文件仍然需要使用相同的编译器主版本进行编译。如果使用,甚至需要有匹配的次要编译器版本。通常,对于C++应用程序,强烈建议确保组成最终二进制(包括关联DLL)的所有翻译单元都用完全相同的编译器编译。 编辑: 以下是整个程序优化文档中的一段引文,它强调了一个事实,即在某些情况下,链接使用不同VS版本编译的库可能不起作用:

当前版本中用/GL生成的文件格式可能不会被VisualC++的后续版本读取。您不应该将包含./OL文件的.LIB文件发送到/gl中,除非您愿意为.VisualC++的所有版本提供.LIB文件的拷贝。您希望用户现在和将来使用。


它确实说您可以链接使用不同工具集版本构建的库(和对象文件)。我怀疑您可以链接使用v141工具集的库和使用v142工具集的可执行文件,只要它们都是使用同一个编译器编译的,尽管我不明白您为什么要这样做。它确实说您可以链接库(和对象文件)使用不同的工具集版本构建。我怀疑您可以将使用v141工具集的库与使用v142工具集的可执行文件链接起来,只要两者都是使用同一个编译器编译的,尽管我不明白您为什么要这样做。我猜,
\u libm\u sse2\u sincos\u
是一个使用SSE的特殊实现,根据需要编译