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)