C++编译OpenCV程序报cv::Mat::Mat()未定义引用链接错误
问题根因
该链接错误和OpenCV安装完整性、符号导出无关,核心是两个配置错误:
- 链接时未显式指定自定义安装OpenCV的库搜索路径,导致链接器优先加载Ubuntu 20.04 apt源自带的OpenCV 4.2.0库,和你引用的4.6.0版本头文件符号不匹配
- 部分测试场景下参数顺序不符合g链接规则:*g链接器严格从左到右解析符号*,源文件、编译预处理参数(-I、-D等)必须放在库链接参数(-l、-L)前面,否则提前扫过的库不会被二次检索,会出现符号明明存在却报未定义的问题。
你观察到的「拷贝初始化写法能正常编译」是编译器返回值优化(RVO)导致的:Mat img = imread(...)写法会被编译器直接优化为在img内存位置构造imread返回的对象,不会生成对cv::Mat::Mat()无参构造函数的符号引用,因此不会触发链接错误,并非代码写法本身有问题。
修复步骤
- 先刷新系统链接器缓存,确保系统能识别/usr/local/lib下的自定义安装库:
sudo ldconfig
- 把自定义OpenCV的pkgconfig路径加入环境变量(可写入~/.bashrc永久生效),避免pkg-config识别到系统旧版本的配置文件:
export PKG_CONFIG_PATH=/usr/local/lib/pkgconfig:$PKG_CONFIG_PATH
- 修正编译命令,保证所有源文件、头文件路径参数在前,库搜索路径、库链接参数放在命令末尾:
- 手动指定链接参数的写法(不需要枚举所有OpenCV库,按需链接即可):
g++ brisk_test.cpp -I/usr/local/include/opencv4 -L/usr/local/lib -lopencv_core -lopencv_highgui -lopencv_imgcodecs -lopencv_imgproc -lopencv_features2d
- 用pkg-config自动生成参数的写法,注意pkg-config的返回值必须放在命令末尾:
g++ brisk_test.cpp `pkg-config --cflags --libs opencv4`
如果要修改你之前写的opencv_linker脚本,不需要调整$@和库参数的顺序(你原来的写法已经是传入参数在前、库参数在后),只需要补充库搜索路径即可:
#!/bin/bash g++ $@ -L/usr/local/lib -lopencv_core -lopencv_highgui -lopencv_imgcodecs -lopencv_imgproc -lopencv_calib3d -lopencv_dnn -lopencv_features2d -lopencv_flann -lopencv_gapi -lopencv_ml -lopencv_objdetect -lopencv_photo -lopencv_stitching -lopencv_videoio -lopencv_video
验证方法
如果还是有问题,可以在编译命令中加-Wl,--verbose参数查看链接过程,确认链接器加载的libopencv_core.so路径是/usr/local/lib下的4.6.0版本,而非/usr/lib下的系统旧版本。
内容的提问来源于stack exchange,提问作者Iascaire
相关产品推荐
相关产品推荐

