關於 extern C 的問題

2021-04-13 09:29:04 字數 2090 閱讀 7911

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語言當中的名字修飾規則非常簡單,只是在函式名字前面新增了下劃...