2011-04-04 64 views
1

我想鏈接靜態庫(.a)文件與.o文件,它應該使用庫中的符號。但是,使用gcc時 - 正常的鏈接器錯誤出現,無論使用.a文件爲g ++ vs gcc,鏈接問題與靜態庫(.a)

gcc -L。 a.c staticlib.a

但是,相同的命令完美地工作於g ++。

這是怎麼發生的?

我可以看到.c文件是完全合法的c(因此C++),但爲什麼gcc不能檢測庫中的符號?

嘗試使用objdump查找庫中的符號,能夠找到非常相似的符號,但不是確切的符號。 e.g:

了 00000000000000b0 G + F的.text 000000000000004e _ * Z15PhttsFn_InitTTSPh * 的符號* PhttsFn_InitTTS *

是否有人可以解釋這種現象?我也檢查過編譯庫文件的體系結構,它與我的體系結構相同。

謝謝!

+0

它看起來像你的庫被編譯爲C++,因此符號名稱被「破壞」,並且入口點只能被C++代碼訪問。 – 2011-04-04 10:55:14

+1

「完全合法的c(因此C++)」C不是C++的子集。 – alternative 2011-04-04 10:55:44

+0

感謝您的答案保羅:) Mathepic,對不起 - 我看到的單詞的選擇很差 - 現在我想起了一些合法的C代碼在C++中是非法的,例如void指針賦值給另一種類型的指針等 – Anonymous 2011-04-04 15:10:05

回答

3

C++使用名爲mangling的東西來命名空間,重載的函數名等,以便在編譯的目標文件中獲得唯一的符號。

您的C代碼明確引用了符號PhttsFn_InitTTS。現在如果編譯爲C,它將生成該符號的名稱。但是,由於C++需要處理同名的所有這些不同變體(例如,使用不同的參數列表進行重載),因此它會創建一個「損壞的」版本編碼名稱空間和參數類型。在你的情況下,它被摧毀到Z15PhttsFn_InitTTSPh,基本上說沒有命名空間和參數。 (我認爲Z15意味着15個字符的名稱,後面沒有參數列表)。

調用GCC作爲gcc允許它挑選文件格式本身,基於文件擴展名(.c - > C,或.cc.cpp等 - > C++)。將其作爲g ++強制使用C++模式。

您的.a文件顯然是使用C++編譯的,因爲它暴露了這個損壞的符號。

+1

nice - now你提到了搗毀 - 我記得前一陣子在C++的旋風版本中閱讀過它,顯然沒有足夠讓我去調試它。非常感謝您的回答! – Anonymous 2011-04-04 15:09:14