平時我們在linux c平台開發的時候,引用了一些Cpp或者C的代碼庫,發現一些頭文件有如下代碼條件編譯。
#ifdef __cplusplus extern "C" { #endif // 代碼 #ifdef __cplusplus } #endif
這個是什么意思呢?一開始看到這個也很茫然。上網查找了一些資料。
主要作用:
為了在C++代碼中調用用C寫成的庫文件,就需要用extern"C"來告訴編譯器:這是一個用C寫成的庫文件,請用C的方式來鏈接它們。
原因:
C++支持函數重載,而C是不支持函數重載的,兩者語言的編譯規則不一樣。編譯器對函數名的處理方法也不一樣。
假設有這個一個函數原型:
void func(int a,int b) { //code }
可能在C++編譯之后會產生_func_int_int之類的名字,因為C++支持重載。而C編譯之后,可能為_func。
關鍵字:extern "C" 表示編譯生成的內部符號名使用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; }
//在C中引用C++函數 //在C中引用C++語言中的函數和變量時,C++的函數或變量要聲明在extern "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
如果我們注意到,很多頭文件都有這樣的用法,比如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; }
參考博文:
http://www.cnblogs.com/HappyXie/archive/2011/01/07/1929369.html