C 和C語言相互呼叫 寫得非常好

2021-07-05 02:34:26 字數 1649 閱讀 2802

注意這裡的c呼叫c++或者c++呼叫c意思是.c檔案中呼叫.cpp檔案中**,或者相反。

整合開發環境如vc++6.0或者vs都是以檔案字尾來區別當前要編譯的是c**還是c++**,然後採用響應的編譯、呼叫協議等。

使用extern "c" 主要是因為c編譯器編譯函式時不帶引數的型別資訊,只包含函式的符號名字。如 

int foo( float x )

c編譯器會將此函式編譯成類似_foo的符號,c聯結器只要找到了呼叫函式的符號,就認為連線成功。

而c++編譯器為了實現函式過載,會在編譯時帶上函式的引數資訊。如它可以把上面的函式編譯成類似於_foo_float這樣的符號。

所以,c呼叫c++,使用extern "c"則是告訴編譯器依照c的方式來編譯封裝介面,當然介面函式裡面的c++語法還是按c++方式編譯。

例如: // c++ code:

class c

;然後,你就可以這樣呼叫 c::f():

//c code

double call_c_f(struct c* p, int i);//宣告

void ccc(struct c* p, int i)

問題:引數struct c* p從**來,即怎麼在c中定義c++物件,其實上面只是說了思想,真實的c中使用c++類需要把原來的類都封裝一下,參看下面的文章

而c++呼叫c,extern "c" 的作用是:讓c++聯結器找呼叫函式的符號時採用c的方式 如:

// c code

void foo( int x );

c++這樣呼叫c函式

// c++ code

extern "c" void foo( int x );

就是讓c++聯結器能過類似於_foo來查詢此函式,而非類似於_foo_int這樣的符號。

時常在cpp的**之中看到這樣的**: 特別是c ++中引入c的標頭檔案,這些c標頭檔案中出現很多如下**。

#ifdef __cplusplus extern "c" #endif

其中__cplusplus是c++編譯器的保留巨集定義.就是說c++編譯器認為這個巨集已經定義了.

所以關鍵是extern "c" {}

extern "c"是告訴c++編譯器件括號裡的東東是按照c的obj檔案格式編譯的,要連線的話按照c的命名規則去找.

要明白為何使用extern "c",還得從cpp中對函式的過載處理開始說起。在c++中,為了支援過載機制,在編譯生成的彙編碼中,要對函式的名字進行一些處理,加入比如函式的返回型別等等.而在c中,只是簡單的函式名字而已,不會加入其他的資訊.也就是說:c++和c對產生的函式名字的處理是不一樣的.

明白了加入與不加入extern "c"之後對函式名稱產生的影響,我們繼續我們的討論:為什麼需要使用extern "c"呢?c++之父在設計c++之時,考慮到當時已經存在了大量的c**,為了支援原來的c**和已經寫好c庫,需要在c++中盡可能的支援c,而extern "c"就是其中的乙個策略。

試想這樣的情況:乙個庫檔案已經用c寫好了而且執行得很良好,這個時候我們需要使用這個庫檔案,但是我們需要使用c++來寫這個新的**。如果這個**使用的是c++的方式鏈結這個c庫檔案的話,那麼就會出現鏈結錯誤.

現在我們有了乙個c庫檔案,它的標頭檔案是f.h,產生的lib檔案是f.lib,那麼我們如果要在c++中使用這個庫檔案,我們需要這樣寫:

extern "c"

C和C 相互呼叫

c和c 相互呼叫 2011 11 01 18 42 29 分類 c c 在專案中融合c和c 有時是不可避免的,在呼叫對方的功能函式的時候,或許會出現這樣那樣的問題。近來在主程式是c語言,而呼叫c 功能函式的時候,c 的 h標頭檔案都能找到,功能函式也都定義了,最重要的是,單獨編譯c 的時候完全沒有問...

C語言與C 語言相互呼叫

1 c 呼叫c中的函式 1.1 c 呼叫c中的函式 正確使用 1 案例原始檔組成 圖12 math模組包含檔案 1 原始檔math.c 圖22 標頭檔案math.h 圖33 主模組包含檔案 1 原始檔main.cpp 圖42 標頭檔案module.h 圖54 編譯math模組 圖65 編譯主模組 圖...

C 和C的相互呼叫

在c專案中融合c 和c的 是實際工程中不可避免的,就如一般底層的驅動是用c寫的,而應用層一般會用c c 的編譯器能相容c語言的編譯器,但他優先以c 的方式編譯 extern關鍵字強制讓c 編譯器對 進行c方式編譯注意 cplusplus 是c 編譯器都內建的乙個巨集,可以用來判斷是不是c 編譯器,那...