From: http://blog.ednchina.com/tianlebo/479334/message.aspx
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++中使用C的函數,或者在C中使用C++的函數。
一://C++引用C函數的例子(C++調用C,extern "C" 的作用是:讓C++連接器找調用函數的符號時採用C的方式 如)
//test.c
#include <stdio.h>
void mytest()
{
printf("mytest in .c file ok\n");
}
//main.cpp
extern "C"
{
void mytest();
}
int main()
{
mytest();
return 0;
}
上述也可以加個標頭檔
//test.h
void mytest()
在後在main.cpp中extern "C"
{
#include “test.h”
}
二://在C中引用C++函數(C調用C++,使用extern "C"則是告訴編譯器把cpp檔案中extern "C"定義的函數依照C的方式來編譯封裝介面,當然介面函數裡面的C++文法還是按C++方式編譯)
在C中引用C++語言中的函數和變數時,C++的函數或變數要聲明在extern "C"{}裡,但是在C語言中不能使用extern "C",否則編譯出錯。(出現錯誤: error C2059: syntax error : 'string',這個錯誤在網上找了很久,國內網站沒有搜到直接說明原因的,原因是extern "C"是C++中的關鍵詞,不是C的,所有會出錯。那怎麼用?看本文,或者搜extern "C"!)
//test.cpp
#include <stdio.h>
extern "C"
{
void mytest()
{
printf("mytest in .cpp file ok\n");
}
}
//main.c
void mytest();
int main()
{
mytest();
return 0;
}
三.//綜合使用
一般我們都將函式宣告放在標頭檔,當我們的函數有可能被C或C++使用時,我們無法確定被誰調用,使得不能確定是否要將函式宣告在extern "C"裡,所以,我們可以添加
#ifdef __cplusplus
extern "C"
{
#endif
//函式宣告
#ifdef __cplusplus
}
#endif
這樣的話這個檔案無論是被C或C++調用都可以,不會出現上面的那個錯誤:error C2059: syntax error : 'string'。
如果我們注意到,很多標頭檔都有這樣的用法,比如string.h,等等。
//test.h
#ifdef __cplusplus
#include <iostream>
using namespace std;
extern "C"
{
#endif
void mytest();
#ifdef __cplusplus
}
#endif
這樣,可以將mytest()的實現放在.c或者.cpp檔案中,可以在.c或者.cpp檔案中include "test.h"後使用標頭檔裡面的函數,而不會出現編譯錯誤。
//test.c
#include "test.h"
void mytest()
{
#ifdef __cplusplus
cout << "cout mytest extern ok " << endl;
#else
printf("printf mytest extern ok n");
#endif
}
//main.cpp
#include "test.h"
int main()
{
mytest();
return 0;
}
關於C++引用C函數和變數的例子還有一個(來自網上,可以google)
兩個檔案:
c檔案:C.c
***********************************************
int external="5"; //全域變數,預設為extern。
int func() //全域函數,預設為extern。
{
return external;
}
***********************************************
cpp檔案:CPP.cpp
***********************************************
#include "iostream"
using namespace std;
#ifdef __cplusplus
extern "C"
{
#endif
extern int external; //告訴編譯器extern是在別的檔案中定義的int,這裡並不會為其分配儲存空間。
extern int func(); //雖然這兩個都是在extern "C"的{}裡,但是仍然要顯式指定extern,否則報錯。
#ifdef __cplusplus //不僅僅是函數,變數也要放在extern "C"中。
}
#endif
void main(void)
{
cout<<"the value of external in c file is: "<<EXTERNAL<<ENDL;
external=10;
cout<<"after modified in cpp is : "<<FUNC()<<ENDL;
}
***********************************************
extern是C/C++語言中表明函數和全域變數作用範圍(可見度)的關鍵字.,它告訴編譯器,其聲明的函數和變數可以在本模組或其它模組中使用。
1。對於extern變數來說,僅僅是一個變數的聲明,其並不是在定義分配記憶體空間。如果該變數定義多次,會有串連錯誤
2。通常,在模組的標頭檔中對本模組提供給其它模組引用的函數和全域變數以關鍵字extern聲明。也就是說c檔案裡面定義,如果該函數或者變數與開放給外面,則在h檔案中用extern加以聲明。所以外部檔案只用include該h檔案就可以了。而且編譯階段,外面是找不到該函數的,但是不報錯。link階段會從定義模組產生的目標代碼中找到此函數。
3。與extern對應的關鍵字是static,被它修飾的全域變數和函數只能在本模組中使用。