OpenCV的运行库和静态库

Runtime libraries and Static libraries of OpenCV

本文关键字:静态 运行 OpenCV      更新时间:2023-10-16

我之前已经发布了两个关于静态库和动态库的问题,并得到了满意的答复。但是仍然有一些缺失的环节。

我能解决我的问题,但我不理解完整的概念。

需要理解的概念:通过我前面问题的回答,我意识到我没有OpenCV的静态库,所以我安装了它们。现在,我在Windows 7中有了OpenCV的静态库。

我做了一个简单的程序来测试OpenCV的静态库的功能。

#include <iostream>
#include "opencvhighgui.h"
#include "opencv2corecore.hpp"
#include "opencv2imgprocimgproc.hpp"
int main()
{
    cv::Mat image(100, 500, CV_8SC3, Scalar(0,0,255));
    std::cout << "nstatic Libs test"<<std::endl;
    return 0;
}

对于以上代码的链接,我使用了OpenCV的静态库。

真正的问题:上面的代码得到编译,链接和运行没有任何问题,如果我在Visual Studio中选择Multi-threaded Debug (/MTd)运行时库。但是如果我选择Multi-threaded Debug DLL (/MDd)运行时库,那么有很多错误看起来像下面(我没有包括所有的错误):

Error   1   error LNK2038: mismatch detected for 'RuntimeLibrary': value 'MTd_StaticDebug' doesn't match value 'MDd_DynamicDebug' in Source.obj 
Error   22  error LNK2005: "public: __cdecl std::_Container_base12::_Container_base12(void)" (??0_Container_base12@std@@QEAA@XZ) already defined in opencv_core2411d.lib(alloc.obj)

我只是想了解一下c++的DLL运行库和OpenCV的静态库之间发生冲突的原因。选择Multi-threaded Debug (/MTd)后,是c++库也得到静态链接?

最后,如果我想静态地链接几个openCV库和动态地链接几个库,应该选择哪个运行时库选项(情况可能看起来很尴尬,但只是问)?

一些背景

/MT/MD与它们的调试等价物(/xxd)在c++运行时中的链接不同。

    /MD链接到c++运行时的dll版本
  • /MT到静态库版本(即链接到二进制文件中的c++运行时所需的内容)

注意:上面的版本都是多线程的,历史上也有单线程的版本,但是这些已经消失了。

错误

你得到这些错误是因为选项是混合的,因此有多个符号的定义-一个来自dll的导入库,一个来自静态库。链接器应该选择哪一个?它无法确定给定冲突的结果,因此出现错误。

…如果我想静态地链接几个openCV库和动态地链接几个库,应该选择哪个运行时库选项…?

不要把它们混在一起。它会导致您正在处理的这些错误。链接c++(和C代码)的一般建议是与如何链接运行时保持一致。

我通常会进一步详细说明所有库的链接之间应该有一致性,无论是静态的还是动态的(当然它们可以混合,但在没有深入了解所涉及的内存和资源问题之前不应该这样做-通常不值得冒险)。

据我所知,动态链接库(dll)和静态库之间的区别在于静态库总是编译到您的代码中,因此与可执行文件静态地加载在内存中,而dll则根据需要加载在内存中,只要它们的函数被正确引用,就不需要编译到您的代码中。

在您的情况下似乎正在发生的事情是,您的静态库正在重新定义一些已经在包含的dll中定义的函数和/或期望从dll中不包含的函数。

根据许可和您的需求,我发现使用外部库来使用dll是最佳实践,因为它们可以(通常)在不重新编译代码的情况下更新,这使得打补丁成为更简单的任务。