extern "C"的主要作用就是爲了能夠正確實現C++代碼調用其他C語言代碼。加上extern "C"後,會指示編譯器這部分代碼按C語言的進行編譯,而不是C++的。由於C++支持函數重載,因此編譯器編譯函數的過程中會將函數的參數類型也加到編譯後的代碼中,而不僅僅是函數名;而C語言並不支持函數重載,因此編譯C語言代碼的函數時不會帶上函數的參數類型,一般之包括函數名。
這個功能十分有用處,因爲在C++出現以前,很多代碼都是C語言寫的,而且很底層的庫也是C語言寫的,爲了更好的支持原來的C代碼和已經寫好的C語言庫,需要在C++中儘可能的支持C,而extern "C"就是其中的一個策略。
這個功能主要用在下面的情況:
1、C++代碼調用C語言代碼
2、在C++的頭文件中使用
3、在多個人協同開發時,可能有的人比較擅長C語言,而有的人擅長C++,這樣的情況下也會有用到
下面給出一個例子:
moduleA、moduleB兩個模塊,B調用A中的代碼,其中A是用C語言實現的,而B是利用C++實現的,下面給出一種實現方法:
1、//moduleA頭文件
#ifndef __MODULE_A_H //對於模塊A來說,這個宏是爲了防止頭文件的重複引用
#define __MODULE_A_H
int fun(int, int);
#endif
2、//moduleA實現文件moduleA.C //模塊A的實現部分並沒有改變
#include"moduleA"
int fun(int a, int b)
{
return a+b;
}
//moduleB頭文件
#idndef __MODULE_B_H //很明顯這一部分也是爲了防止重複引用
#define __MODULE_B_H
#ifdef __cplusplus //而這一部分就是告訴編譯器,如果定義了__cplusplus(即如果是cpp文件, extern "C"{ //因爲cpp文件默認定義了該宏),則採用C語言方式進行編譯
#include"moduleA.h"
#endif
… //其他代碼
#ifdef __cplusplus
}
#endif
#endif
//moduleB實現文件 moduleB.cpp //B模塊的實現也沒有改變,只是頭文件的設計變化了
#include"moduleB.h"
int main()
{
cout<<fun(2,3)<<endl;
}
下面是詳細的介紹:
由於C、C++編譯器對函數的編譯處理是不完全相同的,尤其對於C++來說,支持函數的重載,編譯後的函數一般是以函數名和形參類型來命名的。例如函數void fun(int, int),編譯後的可能是(不同編譯器結果不同)_fun_int_int(不同編譯器可能不同,但都採用了類似的機制,用函數名和參數類型來命名編譯後的函數名);而C語言沒有類似的重載機制,一般是利用函數名來指明編譯後的函數名的,對應上面的函數可能會是_fun這樣的名字。