VS2017的C++开发心得(八)DLL动态链接——Opencv的使用

上一篇对dll的链接使用进行了粗略介绍,这一篇就以Opencv为例子介绍下怎么使用第三方库来进行程序开发。Opencv是世界机器视觉领域非常著名的开源库,里面包含了大量的图形处理算法,变换算法,匹配算法,也包括现在流行的DNN深度学习网络应用。Opencv的强大更在于它的整个库对用Opencl和CUDA的支持非常好,同样的算法,你自己写的运行速度基本没法跟Opencv的运行速度比较。

首先去官网下载Opencv的最新版本:https://opencv.org/releases.html。

4.0.0alpha下载链接:https://sourceforge.net/projects/opencvlibrary/files/4.0.0-alpha/opencv-4.0.0-alpha-vc14_vc15.exe/download。SourceForge对国内网络很不友好,经常会丢失页面,多试几次,下载用迅雷比较快。

目前流行的第三方库基本都是Cmake项目,基于源码使用Cmake来生成VS项目,然后自己编译出所需要的DLL,LIB和PDB文件。这里我就直接下载编译好Openv4.0.0package,想了解Cmake生成的可以自己百度下。我自己也只是使用Cmake,并没有详细研究,就不介绍了。下载完成后的exe是一个7zip的压缩文件,我解压到F盘的SDK中如下:

VS2017的C++开发心得(八)DLL动态链接——Opencv的使用_第1张图片

解压完成是这样的:

VS2017的C++开发心得(八)DLL动态链接——Opencv的使用_第2张图片

如上图所示,Opencv的根目录下有两个文件夹:build和sources,build是我们进行项目开发时所需要的,而sources中的源代码在我们进行debug源代码调试的时候会用到。

库文件安装完成后,我们先看看开发所需要的两个文件夹,include和x64:

VS2017的C++开发心得(八)DLL动态链接——Opencv的使用_第3张图片

include就是存放头文件的文件夹,而x64是opencv在64位系统中生成的.lib,.pdb和.dll文件,分别对应我们链接,调试,运行所需要的文件。我之前使用的是opencv3.0.0版本,这里应该还有个x86文件夹对应32位系统使用的。现在看来opencv有点鼓励我们进行64位程序开发,32位的文件应该就需要自己从源码进行编译了。

第一步,把头文件目录include添加到C/C++的附加包含目录中,添加方式参考第六篇文章:VS2017的C++开发心得(六)头文件的路径问题与属性管理器。如下:

VS2017的C++开发心得(八)DLL动态链接——Opencv的使用_第4张图片

第二步,添加.lib文件的文件夹到链接器的附件库目录下,以及添加opencv_world400d.lib到输入,如下:

VS2017的C++开发心得(八)DLL动态链接——Opencv的使用_第5张图片

VS2017的C++开发心得(八)DLL动态链接——Opencv的使用_第6张图片

这里的输入opencv_world400d.lib,其实可以通过代码加载。因为放在这里可以清晰看到整个项目的依赖项,而不用去每个cpp文件里面查找,所以推荐使用这种输入lib方式。外部项的加载本来就是对于整个项目来讲的,所以不推荐在某个cpp文件里面用代码进行加载lib。

头文件告诉我们这个库的结构体定义和函数接口定义,这是让我们可以通过头文件知道代码该怎么写。而lib文件,是告诉编译器我们使用的这个库的所有的函数的位置在对应名字的dll文件的哪个位置。可以看到,头文件是写代码用的,lib文件是链接dll用的。而dll文件则是运行我们的程序的时候使用的。

我简单写了点代码:

VS2017的C++开发心得(八)DLL动态链接——Opencv的使用_第7张图片

这时候运行代码会出现“找不到xxx.dll文件”:

VS2017的C++开发心得(八)DLL动态链接——Opencv的使用_第8张图片

现在介绍两种方法来解决第三库的DLL路径问题,分别对应Debug和Release开发。

第一种,适用于Debug开发时:

VS2017的C++开发心得(八)DLL动态链接——Opencv的使用_第9张图片

如上图,在系统环境变量里面Path路径下添加上我们的Opencv的Bin文件夹,也就是.dll所在的文件夹路径。这种方法不用额外去拷贝第三方库的.dll文件,方便调试。

第二种方法,适用于Release开发。打开项目属性:

VS2017的C++开发心得(八)DLL动态链接——Opencv的使用_第10张图片

在生成事件中写下以下命令:xcopy "F:\SDK\opencv_400alpha\opencv\build\x64\vc14\bin\opencv_world400d.dll"  "$(SolutionDir)$(Platform)\$(Configuration)" /y 。 即拷贝SDK中的opencv_world400d.dll到我们的生成目录下。每次生成项目时,VS会把我们项目的依赖dll复制到我们的exe的目录下(这里我配置的是Debug):

VS2017的C++开发心得(八)DLL动态链接——Opencv的使用_第11张图片

这样的好处是,你程序的依赖项目都集中在生成目录下,方便最终打包发布。

这里补充说下VS2017的C++开发心得(四)VS的文件夹路径以及项目生成步骤中关于怎么让程序在没有安装VS的Windows系统中运行。首先看下我们的windows/system32文件夹下面关于msvc的dll文件:

VS2017的C++开发心得(八)DLL动态链接——Opencv的使用_第12张图片

这些msvcp文件是我们通过VS编译后的C++程序运行的依赖文件之一。如果我们编译的是Debug版本的c++程序,它依赖的可能就是图上的msvcp140d.dll,就是带d结尾的调试dll。而这个调试dll是只有vs安装后才有的。所以Debug版本生成的exe软件和dll无法在普通Windows上运行。我曾经见过有人的程序把msvcp120d.dll放进去一起发布了,虽然解决了问题,但似乎不了解VS的初衷是想让你发布的是Release版本。Release配置下发布的程序所需的dll一般Win10都自带了,即便有些比较老的系统也可以通过安装 Microsoft Visual C++ Redistributable packages来兼容,下载地址如下:https://support.microsoft.com/en-us/help/2977003/the-latest-supported-visual-c-downloads

 

最后再补充一下前面文章没有详细讲的关于出现链接错误“无法解析的外部符号XXXX”的解决方法。如果碰到以下的问题:

VS2017的C++开发心得(八)DLL动态链接——Opencv的使用_第13张图片

首先确定是哪个项目,如上图所示是Project1的链接错误。然后我们来看看无法解析的外部符号是哪些:cvCreateImage,cvSetZero,cvShowImage,cvWaitKey。这时候就要通过这些符号名判断这些符号是哪个库里面,如上图是Opencv的库函数。那问题其实就是Project1没有输入Opencv的.lib文件导致的。解决方法就是在Project1的输入中加上opencv_world400d.lib。

这类问题的解决方法都一样,先一个项目一个项目的看缺了哪些库,然后在输入里面加上对应的lib。

你可能感兴趣的:(VS)