`_GLIBCXX_USE_CXX11_ABI`有什么作用


最近遇到個問題,在鏈接OpenVINO的時候,需要將libinference_engine.so與libinference_engine_legacy.so都鏈接進去,但如果在CMakeLists里設置add_definitions(-D _GLIBCXX_USE_CXX11_ABI=0),就無法正常鏈接:編譯器只會鏈接libinference_engine_legacy.so,而沒有libinference_engine.so,當設置add_definitions(-D _GLIBCXX_USE_CXX11_ABI=1),就不會出現這樣的情況。並且后續會報出符號未定義的錯,如下所示。

my_lib.so: undefined reference to `InferenceEngine::Core::LoadNetwork(InferenceEngine::CNNNetwork, std::string const&, std::map<std::string, std::string, std::less<std::string>, std::allocator<std::pair<std::string const, std::string> > > const&)'
my_lib.so: undefined reference to `InferenceEngine::Data::getName() const'
my_lib.so: undefined reference to `InferenceEngine::Core::Core(std::string const&)'
my_lib.so: undefined reference to `InferenceEngine::details::InferenceEngineException::InferenceEngineException(std::string const&, int, std::string const&)'
my_lib.so: undefined reference to `InferenceEngine::Core::ReadNetwork(std::string const&, std::string const&) const'

這就比較詭異了,必須好好看看這個_GLIBCXX_USE_CXX11_ABI有什么作用。

參考GCC提供的手冊<Dual ABI>,大概的意思就是說。

在GCC5.1發布的同時,為libstdc++添加了新的特性,其中也包括了std::string和std::list的新實現。這個新的實現使得兩者符合了c++11的標准,具體來說是取消了Copy-On-Write。那么,這樣子雖然符合了c++11的標注,舊版不就無法兼容了嗎。為了避免上述混亂,對於舊版而言,GCC5.1添加了__cxx11命名空間,GCC5.1或者說c++11規范下的string和list,實際上是std::__cxx11::string和std::__cxx11::list,所以我們一般的using namespace std就會變成形如using namespace std::__cxx11的樣子。也就是說,有舊版(c++03規范)的libstdc++.so,和新版(c++11規范)的libstdc++.so兩個庫同時存在。

為了避免兩個庫到底選擇哪一個的麻煩,GCC5.1就引入了-D_GLIBCXX_USE_CXX11_ABI來控制編譯器到底鏈接哪一個libstdc++.so,

-D_GLIBCXX_USE_CXX11_ABI=0 鏈接舊版庫
-D_GLIBCXX_USE_CXX11_ABI=1 鏈接新版庫
所以,回到OpenVINO的那個問題,提示符號未定義,我估計就是因為,OpenVINO這個第三方的庫libinference_engine.so,它是使用c++11規范的libstdc++.so,所以我在引用的時候,也必須使用相同規范的libstdc++.so,否則在這個第三方的內部,std::string就必須改成std::__cxx11::string才能使用_GLIBCXX_USE_CXX11_ABI=0。大概就是這樣子,又學習了呢。


原文鏈接:https://blog.csdn.net/github_28260175/article/details/105922130


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM