標籤:

編譯 C++ 項目時模板引發的「undefined reference to」問題?

問題的場景大概是這樣的:我在嘗試編譯一個C++項目,最終目標是生成一個可執行文件;如果我將所有源文件編譯到.o目標文件,然後再都鏈接到一起,這樣做能夠正常生成一個可執行文件。但如果把除去main函數所在文件以外的所有.o文件先鏈接成一個.so或者.a,然後再把main函數所在的.o文件與這個.so(.a)鏈接,就會導致「undefined reference to」,即缺少符號。現在猜測是由於C++的模板特性引發的,但不是很清楚細節。因為按照我的理解,只要正確引用了包含模板的.h文件,就能夠遞歸地將所有模板引入當前的編譯單元,從而正確生成所有的代碼並編譯,也就不會出現這種情況……

但現在事實是,確實出現了奇怪的鏈接錯誤,所以來請教一下,有做過類似事情的同學能給掃個盲嘛?最好是能具體分析一下,這類錯誤是怎麼引發的。謝謝~


若是出現這樣的問題,.o可以在一起正常工作,但是.a不可以,那麼不應該再從代碼層面找問題了,而應該是linker的問題。linker的尋找順序是從左往右,而不會重複掃,除非指定特定的選項。

於此我推薦一篇特別棒的文章給你,這裡面有分析特定的例子來解釋不同,我相信一定會對你有所啟發和幫助的,Library order in static linking


ld查找符號的時候, 先會在當前的單元內找, 找不到的時候, 再會到後面的單元裡面找, 永遠都是往後面找.

你寫在一起鏈接沒問題, 分開鏈接就有問題, 那說明後面的鏈接單元內有一個符號在自己(以及後面的)那邊找不到, 在前面能找到......

比如以前搞過PhysX庫的鏈接, 靜態庫非常多, 文檔也沒說明鏈接順序. 那麼最簡單粗暴的方法就是, 把所有的.a鏈接兩遍. 第二種辦法就是把所有的.a解壓, 然後所有的.o文件重新打包成一個.a

當然上面說的都是歪門邪道, 正確的做法就是找到依賴順序, 按照依賴的順序去鏈接.

如果出現循環引用, 比如a, b相互依賴, 那麼就先後鏈接a, b, a, 這樣就行了.


允許我無恥的放上自己的博文:

http://m.blog.csdn.net/article/details?id=50725386


-L指定路徑了么


生成庫可能需要顯式的特例化一些模板類


C++ 中的模板類聲明頭文件和實現文件分離後,如何能實現正常編譯?

如果你是把模版類的聲明和定義分開在 .h和.cpp里,就會有這個錯誤,建議你看看上面問題。


undefined reference to `TransparentBlt" 用codeblocks編寫報錯,頭文件中添加了#pragma comment(lib,"msimg32.lib")。這個錯誤是怎麼導致的,如何解決


很多時候這個錯誤是編譯的時候沒有正確載入庫函數,或者是鏈接順序錯誤。


會不會有類的成員函數只定義了,而沒有實現


推薦閱讀:

在哪些領域,C++ 還有著不可替代的優勢?為什麼?
C 語言局部變數,堆與棧的問題?
C++ 內置變數字元串有什麼好的實現思路?
怎麼讓我寫出個零位元組的類了?
各位知友都喜歡用什麼IDE?

TAG:C | 編譯 |