extern "c"
多用在用非c的語言寫的程式意欲呼叫用c寫成的庫。用c寫成的庫里的函式名(肯定是由c編譯器編譯的)都是c的風格——也就是簡單的乙個函式名。比如函式void st_read(ft_t f)在庫里的符號名就是st_read。
那麼在你的程式中(假設是c++寫成的)需要用到這個st_read函式,當然首先要宣告這個函式,讓編譯器知道存在st_read這個符號名。這時,在宣告這個函式時,就需要用extern "c",即:
extern "c" void st_read(ft_t f)
或者
extern "c"
如果不這樣做在編譯時,c++編譯器就會把這個函式名編譯成void_st_read_ft_t***這樣乙個亂七八糟的形式(實際情況有出入),這主要 是c++為了過載而對同名函式做的區分。用這個亂七八糟的名字當然無法引用c庫中的對應函式(上面已說了c庫中的該函式符號名為簡單的st_read)。
另外乙個相反的情況就是你用其他非c語言寫成了庫,你想要c程式能夠呼叫你的庫中的函式,那麼需要將那些需要匯出的函式的宣告用extern "c"修飾。這需要非c編譯器支援extern "c"修飾。
如果不這樣做在編譯時,c++編譯器就會把這個函式名編譯成void_st_read_ft_t***這樣乙個亂七八糟的形式(實際情況有出入),這主要 是c++為了過載而對同名函式做的區分。用這個亂七八糟的名字當然無法引用c庫中的對應函式(上面已說了c庫中的該函式符號名為簡單的st_read)。
林銳的高質量c/c++程式設計有講道,一下是我摘錄的:
如果同名函式僅僅是返回值型別不同,有時可以區分,有時卻不能.例如:
void function(void);
int function (void);
上述兩個函式,第乙個沒有返回值,第二個的返回值是int型別.如果這樣呼叫函式:
int x = function ();
則可以判斷出function是第二個函式.問題是在c++/c程式中,我們可以忽略函式的
返回值.在這種情況下,編譯器和程式設計師都不知道哪個function函式被呼叫.
所以只能靠引數而不能靠返回值型別的不同來區分過載函式.編譯器根據引數為每
個過載函式產生不同的內部識別符號.例如編譯器為示例8-1-1中的三個eat函式產生象
_eat_beef,_eat_fish,_eat_chicken之類的內部識別符號(不同的編譯器可能產生不同
風格的內部識別符號).
如果c++程式要呼叫已經被編譯後的c函式,該怎麼辦
假設某個c函式的宣告如下:
void foo(int x, int y);
該函式被c編譯器編譯後在庫中的名字為_foo,而c++編譯器則會產生像_foo_int_int
之類的名字用來支援函式過載和型別安全連線.由於編譯後的名字不同,c++程式不能
直接呼叫c函式.c++提供了乙個c連線交換指定符號extern"c"來解決這個問題.
例如:
extern "c"
或者寫成
extern "c"
這就告訴c++編譯譯器,函式foo是個c連線,應該到庫中找名字_foo而不是找
_foo_int_int.c++編譯器開發商已經對c標準庫的標頭檔案作了extern"c"處理,所以
我們可以用#include 直接引用這些標頭檔案.
注意並不是兩個函式的名字相同就能構成過載.全域性函式和類的成員函式同名不算
過載,因為函式的作用域不同.例如:
void print(…); // 全域性函式
class a
不論兩個print函式的引數是否不同,如果類的某個成員函式要呼叫全域性函式
print,為了與成員函式print區別,全域性函式被呼叫時應加'::'標誌.如
::print(…); // 表示print是全域性函式而非成員函式
關於extern 「C「 的理解
我們經常在 中看到這樣的宣告 ifdef cplusplus extern c endif 其中 ifdef cplusplus是用來判斷檔案是否為cpp檔案,這個很好理解,那被它限定的extern c 又是什麼意思呢?其實這個extern c 就是表達了兩個含義 1 extern表示內宣告的函式和...
extern 「C」 的含義及解決的問題
c 與c 程式連線問題 它們之間的連線問題主要是因為c c 編繹器對函式名解碼的方式不能所引起的,考慮下面兩個函式 c int strlen char string c int strlen char string 兩個函式完全一樣。在c在函式是通過函式名來識別的,而在c 中,由於存在函式的過載問題...
關於C 中的名字修飾以及 extern C
在c c 中,乙個程式要執行起來,需要經歷以下幾個階段 預處理,編譯,彙編,鏈結.而名字修飾是一種在編譯過程中,將函式,變數的名稱重新改變的機制,簡單來說就是編譯器為了區分各個函式,將函式通過某種演算法,重新修飾為乙個全域性唯一的名稱.在c語言當中的名字修飾規則非常簡單,只是在函式名字前面新增了下劃...