我之前已经发布了两个关于静态和动态库的问题,并得到了满意的答复。但仍有一些缺失的链接。
我能够解决我的问题,但我不明白完整的概念。
要理解的概念:通过我之前question 的响应,我意识到我没有OpenCV的静态库,所以我安装了它们。现在,我在Windows 7中拥有OpenCV的静态库。
我制作了一个如下所示的简单程序来测试OpenCV的静态库的功能。
#include <iostream>
#include "opencv\highgui.h"
#include "opencv2\core\core.hpp"
#include "opencv2\imgproc\imgproc.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库并且动态地连接几个,那么应该选择哪个运行时库选项(情况可能看起来很尴尬而只是问)?
答案 0 :(得分:0)
据我了解,动态链接库(dll)和静态库之间的区别在于静态库总是被编译到你的代码中,因此静态地用可执行文件加载到内存中,而dll根据需要加载到内存中并且需要只要正确引用它们的函数,就不能编译到代码中。
在你的情况下似乎正在发生的事情是你的静态库正在重新定义一些已经在包含的dll中定义的函数和/或期望它不包含的dll中的函数。
根据许可和您的需求,我发现使用外部库来使用dll是最佳做法,因为它们可以(通常)在不重新编译代码的情况下进行更新,这使得修补变得更简单。
答案 1 :(得分:0)
一些背景
/MT
and /MD
及其调试等价物(/xxd
)链接在C ++运行时的方式不同。
/MD
链接到C ++运行时的dll版本/MT
到静态库版本(即链接到二进制文件中的C ++运行时需要什么)注意:上面的版本是多线程的,历史上也存在单线程版本,但这些版本已经消失。
错误
您收到这些错误是因为选项是混合的,因此符号有多个定义 - 一个来自dll的导入库,另一个来自静态库。链接器应该选择哪一个?鉴于冲突,它无法确定结果,因此错误。
不要混合它们。它会导致您正在处理的错误。链接C ++(和C代码)的一般建议是与运行时的链接方式保持一致。...如果我想静态地链接几个openCV库并且动态地链接几个,那么应该选择哪个运行时库选项??
我通常会进一步详细说明所有库的链接之间应该保持一致性,无论是静态还是全部动态(确保它们可以混合使用,但如果没有对内存和资源的深入理解,就不应该这样做涉及的问题 - 通常不值得冒风险。)