GCC4和GCC5使用的C++標準庫下,string的名字不一樣,導致鏈接錯誤。 ...
太長不看版:GCC4和GCC5使用的C++標準庫下,string的名字不一樣,導致鏈接錯誤。
之前在Ubuntu下使用OpenCV的時候一切正常。後來再次編譯的時候,連接器提示有些庫函數找不到:
main.o:在函數‘main’中:
main.cpp:15:對‘cv::imread(std::string const&, int)’未定義的引用
main.cpp:22:對‘cv::namedWindow(std::string const&, int)’未定義的引用
main.cpp:23:對‘cv::imshow(std::string const&, cv::_InputArray const&)’未定義的引用
collect2: error: ld returned 1 exit status
源文件里還使用了其他的庫函數,為什麼只有這幾個函數找不到?後來排除了大量錯誤,確定不是因為找不到庫文件,坑爹的bug。。。
對輸出的目標文件進行分析,列出其符號表:nm -c main.cpp.o
,發現它引用了外部的符號:
...
U cv::imread(std::string const&, int)
U cv::namedWindow(std::string const&, int)
U cv::imshow(std::string const&, cv::_InputArray const&)
...
查找資料,得知這些函數來自opencv_highgui庫文件(/usr/lib/x86_64-linux-gnu/libopencv_highgui.so
),同樣可以列出它的符號表nm -C opencv_highgui.a
(對應的靜態庫):
...
0000000000000000 T cv::imread(std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > const&, int)
0000000000000000 T cv::namedWindow(std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > const&, int)
0000000000000000 T cv::imshow(std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > const&, cv::_InputArray const&)
...
能夠看出庫函數的原型,和我自己的程式中的原型不一致。仔細對比,是標準庫string的名字不一樣。我自己的程式里是std::string
在庫里是std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> >
。
後來才想起,前段時間為了相容MATLAB安裝了GCC4.9版本(和C++標準庫)。再恢復GCC5.x版本編譯、鏈接,沒有再次出現問題。
總結一下,是因為我的OpenCV庫是Ubuntu官方使用C++5的標準庫編譯出來的,而自己寫的程式是C++4.9的庫。兩個庫里標準庫string的名字在目標代碼里不一樣,導致無法鏈接。