1.揭密extern "c"
extern "c"包含雙重含義,從字面上即可得到:首先,被它修飾的目標是 "extern」的;其次,被它修飾的目標是 "c」的。
首先來看一下"extern」的含義:
a.在乙個檔案內,如果外部變數不在檔案的開頭定義,其有效範圍只限定在定義到檔案的結束處。如果在定義前需要引用該變數,則要在引用之前用關鍵字 "extern」 對該變數做「外部變數宣告」,表示該變數是乙個已經定義的外部變數。有個這個宣告,就可以從宣告處起合理地使用該變數了。"extern」起到了擴充套件作用域的作用。
//.c#include void
main()
int a=100;
b.在多檔案的程式中,如果多個檔案都要使用同乙個外部變數,不能在各個檔案中各定義乙個外部變數,否則會出現「重複定義」的錯誤。正確的做法是:在任乙個檔案中定義外部變數,其他檔案用 "extern」對變數做「外部變數宣告」。在編譯和連線時,系統會由此知道該變數是乙個已經在別處定義的外部變數,並把另一檔案中外部變數的作用域擴充套件到本檔案,這樣在本檔案就可以合法地使用該外部變數了。
//file1.c
#include int a = 100;//
定義外部變數
void
main()
extern a;//
宣告a為乙個已定義的外部變數
intpower()
extern只用作宣告,而不用於定義。extern說明變數或者函式定義在其他的原始檔裡,而不用include標頭檔案的方式來引用該函式,在鏈結時,鏈結器在各個模組中搜尋這個變數或者函式來進行最終鏈結。
c.外部函式
在定義函式時,如果在最左端加關鍵字extern,表示此函式是外部函式。c語言規定,如果在定義時省略extern,則隱含為外部函式。而內部函式必須前加static關鍵字;
在需要呼叫此函式的檔案中,用extern對函式作宣告,表示該函式是在其他檔案中定義的外部函式。
"c」的含義:(extern 「c」)
c++通過函式引數的不同型別支援過載機制,編譯器根據引數為每個過載函式產生不同的內部識別符號。例如編譯器為void eat(beef …);void eat(fish …);void eat(chicken …);三個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 直接引用這些標頭檔案。
2.extern "c"程式例項
假設有c檔案:
//c.h#ifndef _c_h_
#define _c_h_
extern
int add(int x, int
y);#endif
//c.cint add(int x, int
y)
在c++下呼叫add()函式
//cplusplus.cpp
#include #include
"c.h
"using
namespace
std;
void
main()
產生錯誤:無法解析的外部符號 "int __cdecl add(int,int)" (?add@@yahhh@z),該符號在函式 _main 中被引用
為了解決這個問題,我們需要使用extern "c"。改寫c檔案
//c.h#ifndef _c_h_
#define _c_h_#ifdef __cplusplus
extern"c
"#endif
#endif
檔案為*.c,__cplusplus沒有被定義,extern "c" {}這時沒有生效,對於c語言只是extern int add(int, int);而編譯c++原始檔,__cplusplus被定義,對於c++他看到的是extern "c" ,編譯器就會知道add(1, 0)呼叫的是c連線。
最後:很多dll的生成檔案(***.c)中常出現extern "c" ,windows採用c語言編譯建立dll,c程式可以正確呼叫dll,而當使用者使用c++呼叫dll時,extern "c" {}就起作用了。
extern C 的用法解析
1.引言 c 語言的建立初衷是 a better c 但是這並不意味著c 中類似c語言的全域性變數和函式所採用的編譯和連線方式與c語言完全相同。作為一種欲與c相容的語言,c 保留了一部分過程式語言的特點 被世人稱為 不徹底地物件導向 因而它可以定義不屬於任何類的全域性變數和函式。但是,c 畢竟是一種...
extern C 的用法解析
1.引言 c 語言的建立初衷是 a better c 但是這並不意味著c 中類似c語言的全域性變數和函式所採用的編譯和連線方式與c語言完全相同。作為一種欲與c相容的語言,c 保留了一部分過程式語言的特點 被世人稱為 不徹底地物件導向 因而它可以定義不屬於任何類的全域性變數和函式。但是,c 畢竟是一種...
extern C 的用法解析
1.引言 c 語言的建立初衷是 a better c 但是這並不意味著c 中類似c語言的全域性變數和函式所採用的編譯和連線方式與c語言完全相同。作為一種欲與c相容的語言,c 保留了一部分過程式語言的特點 被世人稱為 不徹底地物件導向 因而它可以定義不屬於任何類的全域性變數和函式。但是,c 畢竟是一種...