解决undefined reference to `cv::imread(std::string const&, int)'


目录
  • 问题
  • 解决方案
  • 原因
  • 进一步测试
  • 引用

问题

报错信息: undefined reference to `cv::imread(std::string const&, int)'
出现了如上错误我还以为是opencv的链接出现问题,便一直试图解决导入opencv,尝试了多种方式链接库,但最终一直会出现该报错
最终发现是C++ ABI的问题

解决方案

代码中#define _GLIBCXX_USE_CXX11_ABI 0导致了该报错,去掉就可以正常运行了

原因

#define _GLIBCXX_USE_CXX11_ABI 0是让编译链接时采用旧版本的ABI

在GCC 5.1 版本发布的libstdc++(GCC下C++标准库)中,添加了std::basic_string新的实现。新的实现与旧的实现保持共存,但有着不同名字,新的实现叫做std::__cxx11::basic_string, 旧的叫做std::basic_string。
GCC的较新版本在编译时会将std::string类型按c++11下std::__cxx11::basic_string 来处理,这时如果你调用的第三方库在编译时未启用c++11特性,那么其中的std::string实际上是std::basic_string,这两者不能相互转换。#define _GLIBCXX_USE_CXX11_ABI 0就是让自己代码中的std::string按照旧实现编译

但我的OpenCV在编译时用的应该已经是std::basic_string的新实现,所以并不需要设置。如果设置了反而会出现标题所示的错误。
但如果第三方库用的是旧实现,自己的编译器是新版本,则需要加#define _GLIBCXX_USE_CXX11_ABI 0, 否则会出现undefined reference to `cv::imread(std::__cxx11::basic_string, std::allocator > const&, int)'

进一步测试

在不同IDE下,该问题的表现不同,在Visual Studio中加不加#define _GLIBCXX_USE_CXX11_ABI 0都正常运行,不知具体原因。

但在Clion(Windows)下,加不加都出现错误
undefined reference to `cv::imread(std::__cxx11::basic_string, std::allocator > const&, int)'
,可能是Clion忽略了我指定的新版本编译器,链接到旧版本上了,暂时未解决。

在Ubuntu下g++手动编译,不加#define...正常运行,加了报错,符合预期

引用

感谢https://zhuanlan.zhihu.com/p/125197727

相关