extern C 的簡單解析

2021-09-08 16:44:43 字數 2621 閱讀 5558

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 畢竟是一種...