eg.
#ifdef __cplusplus
extern "C" {
#endif
#ifdef __cplusplus
}
extern "C" 包含雙重含義,從字面上即可得到:首先,被它修飾的目标是“extern”的;其次,被它修飾的目标是“C”的。讓我們來詳細解讀這兩重含義。
被extern "C"限定的函數或變量是extern類型的;
extern是C/C++語言中表明函數和全局變量作用範圍(可見性)的關鍵字,該關鍵字告訴編譯器,其聲明的函數和變量可以在本子產品或其它子產品中使用。
被extern "C"修飾的變量和函數是按照C語言方式編譯和連接配接的;
作為一種面向對象的語言,C++支援函數重載,而過程式語言C則不支援。函數被C++編譯後在符号庫中的名字與C語言的不同。例如,假設某個函數的原型為:
void foo( int x, int y );
該函數被C編譯器編譯後在符号庫中的名字為_foo,而C++編譯器則會産生像_foo_int_int之類的名字(不同的編譯器可能生成的名字不同,但是都采用了相同的機制,生成的新名字稱為“mangled name”)。_foo_int_int這樣的名字包含了函數名、函數參數數量及類型資訊,C++就是靠這種機制來實作函數重載的。
如果這個函數在C中編譯成庫,目标檔案中函數名為_func,當這個函數中C++中被調用時,C++的編譯器就會到目标檔案中尋找_foo_int_int,結果找不到,出錯。
是以為了防止這種問題,在C++調用時,将函數聲明前加個extern "C" 告訴C++的編譯器,不要對名字再進修飾,而直接去找_func。
同樣在C++中編譯的函數,如果想讓C來使用,通常也加上extern "C"在編譯時将函數名按C的風格進行修飾。
.可以包含頭檔案,相當于頭檔案中的聲明都加了extern "C"
extern "C"
{
#i nclude <cmath>
}
extern "C"
{
double sqrt(double);
int min(int, int);
}
接下來,我們來看下#ifdef _cplusplus/#endif _cplusplus的作用。很明顯#ifdef/#endif、#ifndef/#endif用于條件編譯,#ifdef _cplusplus/#endif _cplusplus——表示如果定義了宏_cplusplus,就執行#ifdef/#endif之間的語句,否則就不執行。
在這裡為什麼需要#ifdef _cplusplus/#endif _cplusplus呢?因為C語言中不支援extern "C"聲明,如果你明白extern "C"的作用就知道在C中也沒有必要這樣做,這就是條件編譯的作用!在.c檔案中包含了extern "C"時會出現編譯時錯誤。
C++中調用C的代碼
假設一個C的頭檔案cHeader.h中包含一個函數print(int i),為了在C++中能夠調用它,必須要加上extern關鍵字(原因在extern關鍵字那節已經介紹)。它的代碼如下:
?
1 2 3 4 5 6 | |
相對應的實作檔案為cHeader.c的代碼為:
?
1 2 3 4 5 6 | |
現在C++的代碼檔案C++.cpp中引用C中的print(int i)函數:
?
1 2 3 4 5 6 7 8 9 | |
------------------------------------
extern用在變量聲明中常常有這樣一個作用,你在*.c檔案中聲明了一個全局的變量,這個全局的變量如果要被引用,就放在*.h中并用extern來聲明。
轉載于:https://blog.51cto.com/suixinsuixin/1288544