繁体   English   中英

使用基于 Visual Studio 2019 构建的库时,Visual Studio 2015 上的链接错误

[英]Link error on Visual Studio 2015 when using library built on Visual Studio 2019

我在 Visual Studio 2019(使用平台工具集 v142)上将OpenCV编译为静态库,然后编写了一个链接 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 interpolateLanczos4( float x, float* coeffs )
{
    static const double s45 = 0.70710678118654752440084436210485;
    static const double cs[][2]=
    {{1, 0}, {-s45, -s45}, {0, 1}, {s45, -s45}, {-1, 0}, {s45, s45}, {0, -1}, {-s45, s45}};

    if( x < FLT_EPSILON )
    {
        for( int i = 0; i < 8; i++ )
            coeffs[i] = 0;
        coeffs[3] = 1;
        return;
    }

    float sum = 0;
    double y0=-(x+3)*CV_PI*0.25, s0 = std::sin(y0), c0= std::cos(y0);
    for(int i = 0; i < 8; i++ )
    {
        double y = -(x+3-i)*CV_PI*0.25;
        coeffs[i] = (float)((cs[i][0]*s0 + cs[i][1]*c0)/(y*y));
        sum += coeffs[i];
    }

    sum = 1.f/sum;
    for(int i = 0; i < 8; i++ )
        coeffs[i] *= sum;
}

其中使用std::sin()std::cos() ,它们在corecrt_math.h中声明。 因此,我猜想丢失的符号与libmxxxcrt.lib 最后,我在 Windows 10 SDk 中找到了一个ucrt.lib ,但它也不起作用。 谁能帮帮我?

你误解了微软解释的二进制兼容性的范围。 跨编译器版本兼容的是具有任何版本的 C++ 运行时的最终可执行文件(和关联的 DLL)。 也就是说,您可以使用 VS2019 编译您的应用程序,并使用 VS2017/15 附带的 C++ 运行时库可再发行组件包。 只有当您使用动态链接的运行时,这才是您关心的事情。 在实践中,这意味着如果出于某种原因,您发布了一些使用 VS2015/v140 工具集编译的可执行文件和一些使用 VS2017/v141 工具集编译的可执行文件,您只需要让用户安装一个 C++ 运行时可再发行组件。 如果您不控制系统上存在的 C++ 运行时的确切版本,这是一个巨大的优势(在某些接受第三方插件的嵌入式系统中可能是这种情况,这些插件必须作为 DLL 分发并且无法安装其他资产)。

然而,形成这个最终可执行文件的所有目标文件仍然需要使用相同的编译器主版本进行编译。 如果您使用完整的程序优化,您甚至需要具有匹配的次要编译器版本。 通常,对于 C++ 应用程序,强烈建议确保构成最终二进制文件(包括关联的 DLL)的所有翻译单元都使用完全相同的编译器进行编译。

编辑:

这是整个程序优化文档的引用,它强调了一个事实,即链接使用不同 VS 版本编译的库在某些情况下可能不起作用:

在当前版本中使用 /GL 生成的文件格式可能无法被后续版本的 Visual C++ 读取。 您不应发送由使用 /GL 生成的 .obj 文件组成的 .lib 文件,除非您愿意为您希望用户现在和将来使用的所有 Visual C++ 版本发送 .lib 文件的副本。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM