研究了一下關於c/c++編譯器關於匯出函式的不同處理
剛剛我在用試驗ffmpeg解碼庫解碼視訊檔案的時候,寫好了但是提示連結錯誤,就網上找了一些文章,現在總結一下,如有錯誤或不嚴謹的地方請告之,免得我坑害別人,先謝過了!
總所周知,c++相容c,但是在c++中呼叫純c寫的庫時,編譯連結目標檔案的時候回提示找不到識別符號,這是因為c++支援過載和多型的而c不支援的緣故.所謂過載就是函式名相同而引數個數或者引數型別不同,c++編譯器在處理這個問題的時候是把函式名寫成函式名+引數型別的形式,比如:int sum(int,int);c++編譯器編譯在符號表的名字是_sum_int_int(過載和多型其實就是編譯器幫了個小忙), 而c編譯器編譯在符號表中的函式名是_sum;所以在C++專案中呼叫純C庫匯出的函式時會編譯連結目標檔案時錯誤提示找不到函式,因為C編譯器匯出的符號不帶引數型別資訊,而C++編譯器在連結時是按照有引數型別的名字來找函式的,所以LINK:error.
方法二不改庫,在C++專案中載入標頭檔案的#include語句用extern "C"{}的花括號包起來,這樣C++編譯器也會以C的規則生成函式符號去找函式進行連結.
extern "C"也不可亂用,比如你用他包住一個全域性變數和一個類的宣告,而類中一個成員變數和全域性變數重名,普通情況下這樣做是沒有問題的,那是因為按照C++的編譯規則會把同名成員變數在符號庫中的名字是 "類名.變數名"這種形式的,而加上extern "C"之後編譯符號庫中的名字就會是 "變數名",全域性變數在符號庫中的名字也是"變數名",此時重複了產生編譯錯誤.