C和C 混合程式設計FAQ

2021-07-11 10:39:41 字數 4685 閱讀 5756

僅僅只需要在你的c++**中將要呼叫的c函式使用extern進行宣告即可,**如下:

//c++ code

extern

"c"void f(int); //方式一

extern

"c"

void code(int i,double d)

在你的c**中對上述幾個呼叫的函式就行定義即可,定義如下:

// c code

void f(int i)

int g(double d)

double h()

在c++中定義的函式,需要顯示的使用extern進行宣告,目的是讓編譯器不對其進行名稱mangle,**如下:

// c++ code:

extern "c" void f(int);

void f(int i)

將上面的**編譯成動態庫,然後交由c動態的去呼叫。下面是在c中如何去呼叫

/* c code: */

void f(int);

void cc(int i)

c呼叫c++的非成員函式就用如上的方式即可完成,那麼c如何去呼叫c++的類成員函式呢?**如下:

#include 

using

namespace

std;

class c

};extern

"c" c* getc()

extern

"c"void delc(c *data)

extern

"c"double call_c_f(c* p,int i)

上面定義了乙個class c,在這個class c中有我們需要呼叫的f函式,為了可以呼叫這個f函式,我們需要提供乙個call_c_f這個函式。在這個函式中通過乙個具體的物件指標來呼叫f函式,為了得到物件指標我們提供了getc函式來例項化乙個class c,通過指標傳遞給c函式來使用。下面是c中呼叫c++的方法:

#include 

struct c;

/* c code: */

double call_c_f(struct

c *p, int i);

struct

c *getc();

void delc();

void ccc(struct c* p, int i)

int main()

首先是對call_c_f,getc,delc三個函式的乙個宣告,然後就是前向宣告class c,因為c中沒有class的概念,因此轉而使用了struct。首先通過getc得到類c的物件指標,然後傳遞給call_c_f即可,在使用完成後呼叫delc釋放物件指標。

到此為止c可以呼叫c++的非成員函式和成員函式了,那麼如果去呼叫c++中的過載函式呢,這個比較簡單,**如下:

// c++ code:

void f(int);

void f(double);

extern

"c"void f_i(int i)

extern

"c"void f_d(double d)

其實就是給每乙個過載的實列都包裹一下即可。就跟c呼叫c++的非成員函式乙個樣子。

在c++的**中去包含標準c的標頭檔案基本上不需要做什麼特殊的改變,直接#include某個標準庫檔案即可,比如stdio.h,同樣你可以使用

cstdio。**如下:

/* this is c code that i'm compiling using a c++ compiler */

#include /* nothing unusual in #include line */

int main()

說白了stdio.hcstdio的區別就是乙個c版本的,乙個是c++版本的,其中c++版本的就是將stdio.h中的內容加入到了c++的std命名空間中,下面的例子中包含了cstdio並引用了std命名空間中的printf函式

// this is c++ code

#include // nothing unusual in #include line

int main()

如果你要在你的c++**中包含一些c的非標準庫標頭檔案,那麼你需要使用extern "c"宣告,告訴c++編譯器標頭檔案中包含的是c函式。

// this is c++ code

extern "c"

int main()

在c++中為了包含c的非標準庫的標頭檔案我們需要將標頭檔案的包含語句放在extern "c"宣告中,你一定很奇怪為什麼c標準庫不需要這樣呢?因為c標準庫中做了一些手腳,不信你可以看看stdio.h的原始碼,你會發現在這個標頭檔案的開始有乙個__begin_decls,結尾有乙個__end_decls。這兩個巨集的定義如下:

#if defined(__cplusplus)

#define __begin_decls extern "c"

#else

#define __begin_decls

#define __end_decls

#endif

哈哈,看到這裡我相信大家應該明白了吧,如果stdio.h被包含在c++的**中那麼__begin_decls__end_decls就夠成了乙個extern "c" {}將整個標頭檔案包含在裡面了,就等同於extern "c"。那麼如何改造我們的標頭檔案讓其可以直接#include到c++的**中呢?

setp1: 將下面的這行放在標頭檔案的開始處,通過判斷是否有__cpluscplus判定是被包含在c**中,還是c++**中

#ifdef __cplusplus

extern

"c"

#endif

到此為止你可以直接將乙個非標準庫的標頭檔案#include到你的c++**中了。

下面是乙個完整的示列。

/* this header can be read by both c and c++ compilers */

#ifndef fred_h

#define fred_h

#ifdef __cplusplus

class fred ;

#else

typedef

struct fred

fred;

#endif

#ifdef __cplusplus

extern

"c"

#endif

#endif /*fred_h*/

上面這個標頭檔案可以被c和c++包含,當被c包含的時候就是乙個fred類和c風格的c_functioncplusplus_callback_function的宣告。

// this is c++ code

#include

"fred.h"

fred::fred() : a_(0)

void fred::wilma(int a)

fred* cplusplus_callback_function(fred* fred)

這是c++的fred的類實現.

/* this is c code */

#include "fred.h"

void c_function(fred* fred)

這是一段c**,包含了fred.h,因此有struct fred宣告,參考如何在c中呼叫c++的函式?一節。因為c中沒有class所以只能用struct來表示,並且class在大多數情況下其記憶體布局都和c中的struct不一樣,因此這裡只能選擇使用指標。

// this is c++ code

#include "fred.h"

int main()

這是一段c++**,同樣包含了fred.h,因此有了class fread宣告,fred.c是其定義, 同時還包含了c風格的c_funcioncplusplus_callback_function宣告,參考如何在c++中呼叫c函式?一節

how to mix c and c++

C 和C 混合程式設計

由於歷史原因,很多時候我們的 並不完全是使用.net寫成的。這時候和以往c 的混合程式設計就顯得相當重要了。最近碰到了這樣的問題,將方法簡要記述如下。要在c 中呼叫c 函式,大體的思路是這樣的 首先將c 函式寫成dll形式的庫,然後在c 中匯入dll中的函式進行呼叫。具體的 類似這樣 c 1int ...

C 和C 混合程式設計

由於歷史原因,很多時候我們的 並不完全是使用.net寫成的。這時候和以往c 的混合程式設計就顯得相當重要了。最近碰到了這樣的問題,將方法簡要記述如下。要在c 中呼叫c 函式,大體的思路是這樣的 首先將c 函式寫成dll形式的庫,然後在c 中匯入dll中的函式進行呼叫。具體的 類似這樣 c 1 int...

C和C 混合程式設計

1 pragma once 關於 pragma once vc 及g 都支援,大膽的用吧。匯出型別必須一致.要麼是c的,要麼是c 2.cplusplus 這個是必須的 ifdef cplusplus extern c endif c 中呼叫c的 1 對於 c 中非類的成員函式,可以簡單的在函式宣告前...