OpenCv在win下静态库的编译和使用,以及部分无法解析外部符号的错误解决

时间:2021-03-02 19:52:42

这里演示的是opencv3.4版本的编译和使用过程。

1、静态库编译

CMake进行配置,编译时我选择build目录为build-static。

OpenCv在win下静态库的编译和使用,以及部分无法解析外部符号的错误解决

其中需要设置

选择安装目录,设置   “CMAKE_INSTALL_PREFIX”  为   /build-static/install   (这里是自动选择的,可自行更改)

编译静态库,取消勾选 “BUILD_SHARED_LIBS”

另外,可以选择勾选 BUILD_opencv_world, 好处是工程添加依赖项只有一个,坏处是这个lib会非常大。(我这里选择了编译生成opencv_world).

配置完成,在vs中编译项目 install 即可。我的生成结果(包括debug和release的2个库)如下:

OpenCv在win下静态库的编译和使用,以及部分无法解析外部符号的错误解决  OpenCv在win下静态库的编译和使用,以及部分无法解析外部符号的错误解决

OpenCv在win下静态库的编译和使用,以及部分无法解析外部符号的错误解决

2、静态库使用

新建一个项目,我这里为了显示明显,lib依赖库的导入采用在源文件中编写 #pragma comment( lib, "***" ) 的形式,也可以在项目属性依赖项中添加(如果之前编译opencv没有选择opencv_world,这里就需要加入工程中需要的lib,项目庞大时,需要添加其他模块的lib,  opencv2版本就是这样)。这里的项目是Release版,所以后面的lib都是不带d的,注意区分。

#include <opencv2/opencv.hpp>

#pragma comment(lib,"IlmImf.lib") 
#pragma comment(lib,"ippicvmt.lib")
#pragma comment(lib,"ippiw.lib") 
#pragma comment(lib,"ittnotify.lib") 
#pragma comment(lib,"libjasper.lib") 
#pragma comment(lib,"libjpeg.lib") 
#pragma comment(lib,"libpng.lib") 
#pragma comment(lib,"libtiff.lib") 
#pragma comment(lib,"libwebp.lib") 
#pragma comment(lib,"zlib.lib")

#pragma comment(lib,"opencv_world340.lib")

using namespace cv;
using namespace std;
int main() 
{ 
    Mat img = imread("1.jpg"); 
    imshow("test", img);
    Mat gray; 
    cvtColor(img, gray, cv::COLOR_BGR2GRAY); 
    imshow("g", gray);
    waitKey(0);
}


编译时,可能会提示很多关于cuda的符号无法解析,比如cudaDevice 、cudaEvent、cudaGetError、cudaHost、cudaMemory、cudaStream、cudaRegister等等。下图是部分错误截图,在文件列中可以看到对应的obj文件。

OpenCv在win下静态库的编译和使用,以及部分无法解析外部符号的错误解决

这个错误是因为我们在编译opencv时使用了cuda,现在简单的度图片显示的项目加载opencv静态库后,还需要加入cuda的静态库。(如果opencv未使用cuda,这里就不会有该错误了)

那么加入下一行,即可解决以上错误。

#pragma comment(lib,"C:/Program Files/NVIDIA GPU Computing Toolkit/CUDA/v8.0/lib/x64/cudart_static.lib")   

另外如果是读摄像头的程序,会出现其他的无法解析符号错误,如ICOpen、ICClose、AVIFile、AVIStream等,同样注意文件列提示。

OpenCv在win下静态库的编译和使用,以及部分无法解析外部符号的错误解决

   opencv项目编译生成的相关的静态库都已经全部加入,但是仍然不能通过。说明还有其他库没有添加进来。可以看到,这些未解析的符号,都是来自于cap_vfw.obj文件,那么我们进一步需要加入win32下的一个库,也就是添加下一行

#pragma comment( lib, "vfw32.lib" )

添加之后,编译正常。

Tips: 如果出现其他符号未解析,都是缺少依赖库的原因,可以根据错误提示找到需要添加的库并加入就行。