標籤:報錯 編譯 word clu 包括 設立 ++ data nbsp
C++中extern "C"的設立動機是實現C++與C及其他語言的混合編程。
C++為了支援函數的重載。C++對全域函數的處理方式與C有明顯的不同。
對於函數void foo( int x, int y );該函數被C編譯器編譯後在符號庫中的名字為_foo。而C++編譯器則會產生像_foo_int_int之類的名字。
extern是C/C++語言中表明函數和全域變數作用範圍(可見度)的keyword。該keyword告訴編譯器。其聲明的函數和變數能夠在本模組或其他模組中使用。
通常。在模組的標頭檔裡對本模組提供給其他模組引用的函數和全域變數以keywordextern聲明。 比如,假設模組B欲引用該模組A中定義的全域變數和函數時僅僅需包括模組A的標頭檔就可以。這樣,模組B中調用模組A中的函數時,在編譯階段,模組B儘管找不到該函數。可是並不會報錯。它會在串連階段中從模組A編譯產生的目標代碼中找到此函數。
與extern相應的keyword是static。被它修飾的全域變數和函數僅僅能在本模組中使用。因此,一個函數或變數僅僅可能被本模組使用時,其不可能被extern “C”修飾。
被extern "C"修飾的變數和函數是依照C語言方式編譯和串連的。
比如:如果在C++中:
// 模組A標頭檔 moduleA.h
int foo( int x, int y );
在模組B中引用該函數:
// moduleB.cpp
#include "moduleA.h"
foo(2,3);
實際上,在串連階段。連接器會從模組A產生的目標檔案moduleA.obj中尋找_foo_int_int這種符號!
加extern "C"聲明後,模組A的標頭檔變為:
// 模組A標頭檔 moduleA.h
extern "C" int foo( int x, int y );
在模組B的實現檔案裡仍然調用foo( 2,3 ),其結果是:
(1)模組A編譯產生foo的目標代碼時。沒有對其名字進行特殊處理,採用了C語言的方式;
(2)連接器在為模組B的目標代碼尋找foo(2,3)調用時。尋找的是未經改動的符號名_foo。 假設在模組A中函式宣告了foo為extern "C"類型,而模組B中包括的是extern int foo( int x, int y ) 。則模組B找不到模組A中的函數;反之亦然。
在C語言的標頭檔裡,對其外部函數僅僅能指定為extern類型。C語言中不支援extern "C"聲明。在.c檔案裡包括了extern "C"時會出現編譯語法錯誤。在C中引用C++語言中的函數和變數時。C++的標頭檔需加入extern "C",可是在C語言中不能直接引用聲明了extern "C"的該標頭檔。應該僅將C檔案裡將C++中定義的extern "C"函式宣告為extern類型。比如://C++標頭檔 a.h
extern "C" int foo( int x, int y );
//C++實現檔案 a.cpp
#include "a.h"
int foo( int x, int y ){return x + y;}
/* C實現檔案 b.c
這樣會編譯出錯:#include "a.h" */
extern int foo( int x, int y );
int main( int argc, char* argv[] ){ foo( 2, 3 ); return 0;}
extern "C" 的含義:????實現C++與C及其他語言的混合編程