未定义的引用_G++ _GLIBCXX_USE_CXX11_ABI 编译报错:std::basic_string与std::__cxx11::basic_string无法匹配的问题

1、原因:

GCC 5在编译时会将std::string类型按c++11下std::__cxx11::basic_string<char> 来处理,这时如果你调用的库在编译时未启用c++11特性则其中的std::string实际上是std::basic_string<char> ,如果将c++11下的string当作参数传入非c++11的库时,就会出现error: cannot convert 'const std::__cxx11::basic_string<char>' to 'const char*',或者未定义的方法引用(undefined reference)。
参考链接:https://blog.csdn.net/ufolr/article/details/52669333

进入 GCC 安装目录,进入 include/c++/5.4.0 目录,然后查看 x86_64-unknown-linux-gnu/bits/c++config.h,或者在(/usr/include/x86_64-linux-gnu/c++/5/bits/c++config.h)关键的宏定义:

#if _GLIBCXX_USE_CXX11_ABI
namespace std
{
  inline namespace __cxx11 __attribute__((__abi_tag__ ("cxx11"))) { }
}
namespace __gnu_cxx
{
  inline namespace __cxx11 __attribute__((__abi_tag__ ("cxx11"))) { }
}
# define _GLIBCXX_NAMESPACE_CXX11 __cxx11::
# define _GLIBCXX_BEGIN_NAMESPACE_CXX11 namespace __cxx11 {
# define _GLIBCXX_END_NAMESPACE_CXX11 }
# define _GLIBCXX_DEFAULT_ABI_TAG _GLIBCXX_ABI_TAG_CXX11
#else
# define _GLIBCXX_NAMESPACE_CXX11
# define _GLIBCXX_BEGIN_NAMESPACE_CXX11
# define _GLIBCXX_END_NAMESPACE_CXX11
# define _GLIBCXX_DEFAULT_ABI_TAG

查看bits/basic_string.h

#if _GLIBCXX_BEGIN_NAMESPACE_CXX11
// line 52~2441
_GLIBCXX_END_NAMESPACE_CXX11
#else  // !_GLIBCXX_USE_CXX11_ABI
  // Reference-counted COW string implentation
  // ...
#endif

也就是说使用老版本的gcc编译或者-D_GLIBCXX_USE_CXX11_ABI=0,std::string会使用旧版本的std::basic_string。但是使用新版本gcc编译,std::string会使用str::__cxx11::basic_string。所以如果编译时链接的库使用不同版本gcc或者编译选项不同,会出现类似如下错误:

libboost_regex.so.1.72.0: undefined reference to `std::__cxx11::messages<char> const& std::use_facet<std::__cxx11::messages<char> >(std::locale const&)@GLIBCXX_3.4.21'

 

2、如果不涉及string,单纯使用自己实现代码编译的库,可以通过如下方式在编译时添加cxx11作用域:

#  define DUAL_ABI cxx11 __attribute__((abi_tag("cxx11")))

namespace ClassA {
  inline namespace DUAL_ABI {
    // library goes here
  }
}

这样可以解决类似undefined reference to `std::_cxx11::funa()`的问题。

3、否则,只能使用对应的编译选项或者gcc版本

4、查看编译符号命令

strings 查看符号和c++filt 解释符号

strings libfuna.so | grep init
#_ZN12TensorRT_SDK4initESsi #找到相关的信息
c++filt _ZN12TensorRT_SDK4initESsi
#TensorRT_SDK::init(std::basic_string<char, std::char_traits<char>, std::allocator<char> >, int)

 

posted @ 2021-11-23 16:27  鸭子船长  阅读(2310)  评论(0编辑  收藏  举报