1. 程式人生 > 實用技巧 >C與C++的互相呼叫!就像大學宿舍一樣,我用你的,你用我的!

C與C++的互相呼叫!就像大學宿舍一樣,我用你的,你用我的!

    注意,本文的前提是,c程式碼採用gcc等c語言編譯器編譯c程式碼,採用g++等c++編譯器編譯c++程式碼,如果c和c++程式碼統一使用g++編譯,大部分情況是可以實現兩者程式碼相互呼叫的。

以下為踩坑過程的總結o_O||。

C 與 C++ 的函式區別

要了解兩者之間如何實現相互呼叫,必須先了解c與c++之間的函式有什麼不同。

c++作為c語言的升級版,兩者必然有很多不同之處。

其中有一個重大不同點就是,c++支援函式過載,而c語言不支援。為了使函式支援過載,c++在c語言的基礎上,將函式名新增上返回值和引數的型別資訊。

例如,int add(int, int)這個函式,通過c++編譯器編譯後,可能呈現的函式名為int int_add_int_int(int, int)

(注:此處為大概地說明c++是如何將返回值和引數資訊新增到函式名中的,實際中編譯器不一定是這樣實現的)。

從以上說明可以得出,由於c++對函式過載的支援,使得編譯後的函式符號與c語言的不一致,即使是在兩者函式名相同的前提下。

extern "C"的作用

那麼,c與c++是不能相互呼叫了嗎?答案是否定的,因為存在著extern "C"這個關鍵字可以使語句可以按照類C的編譯和連線規約來編譯和連線,而不是C++的編譯的連線規約。這樣在類C的程式碼中就可以呼叫C++的函式or變數等。

注意:extern "C"指令中的"C",表示的一種編譯和連線規約,而不是一種語言。"C"表示符合C語言的編譯和連線規約的任何語言,如Fortran、assembler等。

還有要說明的是,extern "C"指令僅指定編譯和連線規約,但不影響語義。例如在函式宣告中,指定了extern "C",仍然要遵守C++的型別檢測、引數轉換規則。

C++ 中呼叫 C 程式碼

對於c++,由於c++的編譯器對c語言相容,因此在c++中呼叫c語言編寫的函式,只需要在函式宣告前面加上關鍵字extern "C",表示採用類c語言的方式解析函式符號。例子如下:

// add.h

#ifdef __ADD_H__

#define __ADD_H__

extern "C" int add(int a, int b);

#endif

// add.c

int add(int a, int
b) { return a + b; } // main.cc #include <iostream> #include "add.h" using namespace std; int main() { cout << "1 + 1 = " << add(1, 1) << endl; }

在例子中,main.cc為c++程式碼,add.c為c語言程式碼,當c++編譯器識別到extern "C"`關鍵字時,會去尋找add函式的實現而不是尋找類似int_add_int_int這樣帶引數資訊的函式實現。

C 語言呼叫 C++ 程式碼

c語言呼叫c++程式碼卻並不容易,原因是c語言並不相容c++。

就算c語言可以呼叫c++,也會因為無法識別c++新定義的符號而編譯報錯。

因此,為了實現c語言呼叫c++函式,必須實現以下兩個步驟:

1.將c++相關函式封裝為靜態庫或動態庫(因為呼叫庫函式時編譯器並不知道里面執行的是什麼語言);

2.對外提供遵循類c語言規約的介面函式。

例子如下所示:

// printNum.h

#ifdef __PRINTNUM_H__

#define __PRINTNUM_H__

extern "C" void printNum(int a);

#endif

// printNum.cc

#include <iostream>

#include "printNum.h"

using namespace std;

void printNum(int a)

{

    cout << << "num is " << a << endl;

}

// main.c

extern void printNum(int a);

printNum(5);

通過將cout函式封裝為類c語言規約的介面函式,使得main.c中可以成功呼叫c++函式printNum

值得注意的是,main.c不可以直接引入printNum.h,因為c語言不能識別extern "C"關鍵字。可以利用c++預定義巨集實現標頭檔案的改寫:

#ifdef __PRINTNUM_H__

#define __PRINTNUM_H__

#ifdef __cplusplus

extern "C" {

#endif

void printNum(int a);

#ifdef __cplusplus

}

#endif

#endif
#ifdef __PRINTNUM_H__

#define __PRINTNUM_H__

#ifdef __cplusplus

extern "C" {

#endif

void printNum(int a);

#ifdef __cplusplus

}

#endif

#endif

小結

✿ c語言與c++的相互呼叫可以通過extern "C"關鍵字實現

✿c++中呼叫c程式碼,只須在c++中為c程式碼函式宣告之前加上extern "C"

✿c語言呼叫c++程式碼,則需要將c++程式碼編譯成靜態庫或動態庫,然後對外提供用extern "C"宣告的類c封裝函式


不管你是轉行也好,初學也罷,進階也可——值得關注進入】的C/C++程式設計學習進階俱樂部

涉及到:C語言、C++、windows程式設計、網路程式設計、QT介面開發、Linux程式設計、遊戲程式設計、黑客等等......


一個活躍、高格調、高層次的程式設計師程式設計學習殿堂;程式設計入門只是順帶,思維的提高才有價值!