如何在同一個程式中混合使用C++和C
1.名變換
名變換,就是C++編譯器給程式的每個函數換一個獨一無二的名字。
由函數名和參數組合產生一個新的名字,這樣為了支援函數重載
在C語言中,這樣的做法是不必要的,因為它沒有重載函數。
這樣就存在一個問題:就是當你在C++環境中調用C函數庫中的函數時,比如一個drawLine(int x,int y)。經過C++編譯器後在obj中的函數名稱可能是drawLine_int_int,這樣當你試圖將obj檔案連結為程式時,將得到一個錯誤。因為連結程式無法在C函數庫中找到drawLine_int_int。
要解決這個問題,你需要一種方法來告訴C++編譯器不要在這個函數上進行名變換。你不期望對用其它語言寫的函數進行名變換,如C、彙編、Fortran、LISP、Forth或其它。
總之,如果你調用一個名字為drawLine的C函數,它實際上就叫drawLine,你的obj檔案應該包含這樣的一個引用,而不是引用進行了名變換的版本。
extern "C"
void drawLine(int x1, int y1, int x2, int y2);
不要以為有一個extern 'C',那麼就應該同樣有一個extern 'Pascal'什麼的,這裡extern ‘C’應看做是聲明這個函數應該被當做好像是C寫的一樣來進行調用,要禁止名稱變換。
你甚至可以在C++函數上申明extern 'C'。這在你用C++寫一個庫給使用其它語言的客戶使用時有用。通過禁止這些C++函數的名變換,你的客戶可以使用你選擇的自然而直觀的名字,而不用使用你的編譯產生的變換後的名字。
如果你有一堆函數不想進行名變化,那麼你可以簡單的通過加一對大括弧來實現
extern "C" { // disable name mangling for// all the following functionsvoid drawLine(int x1, int y1, int x2, int y2);void twiddleBits(unsigned char bits);void simulate(int iterations);...}
通過定義一個宏,我們可以輕鬆的控制是否需要添加extern "C"。比如程式放在C++編譯器下編譯時間我們需要添加extern "C",而在C編譯器下編譯時間就不需要了。
下面的功能就是,當我們定義了_cplusplus這個宏的話,說明是在C++環境下,那麼條件編譯指令將被執行,也就是定義extern "C",否則是在C環境下,不會定義。
#ifdef __cplusplusextern "C" {#endifvoid drawLine(int x1, int y1, int x2, int y2);void twiddleBits(unsigned char bits);void simulate(int iterations);...#ifdef __cplusplus}#endif
這裡我們還需要知道一點是,不同的編譯器可能使用了不同的名稱變換規則。所以當你連結由不同的編譯器得來的obj的時候,如果出現連結錯誤,那就不要感到吃驚了。
2.動態記憶體分配
嚴格遵守:C++部分使用new和delete,C部分使用malloc和free。
new分配的記憶體使用量delete釋放,malloc分配的記憶體用free釋放。
3.資料結構的相容性
如果在C++和C之間傳遞資料,我們不能期望C的函數能夠瞭解或支援C++的特性,也就是說它們的互動必須限定在C可支援的概念上。