程序師世界是廣大編程愛好者互助、分享、學習的平台,程序師世界有你更精彩!
首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫知識
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
 程式師世界 >> 編程語言 >> C語言 >> C++ >> C++入門知識 >> C/C++混合編程

C/C++混合編程

編輯:C++入門知識

 

C中調用C++,C++中調用C都會用到extern "C",但兩者的意義卻大不一樣!!

 

 

 

 

先介紹在C++中調用C,這個大家都比較熟悉:

 

例:

 

//C代碼

 

<span style="font-family:Microsoft YaHei;font-size:18px;">void foo( int x );

</span>

 

//C++代碼

 

<span style="font-family:Microsoft YaHei;font-size:18px;">//C++ code

extern "C" void foo( int x );

</span>讓C++連接器能通過過類似於_foo來查找此函數,而非類似於_foo_int這樣的符號。

 

 

使用extern "C"則是告訴編譯器依照C的方式來編譯封裝接口,當然接口函數裡面的C++語法還是按C++方式編譯。使用extern "C"則是告訴編譯器依照C的方式來編譯封裝接口,當然接口函數裡面的C++語法還是按C++方式編譯。

 

 

 

 

再來說說C中調用C++,這其中也會用到extern "C",這則是告訴編譯器依照C的方式來編譯封裝接口,當然接口函數裡面的C++語法還是按C++方式編譯。

 

C++代碼:(非成員函數)

 

<span style="font-family:Microsoft YaHei;font-size:18px;">extern "C" int foo( int x );

int foo( int x )

{

   //...

}</span>這樣,編譯器會將foo函數編譯成類似_foo符號,而不會編譯成類似_foo_int符號。

 

 

 

C代碼

 

<span style="font-family:Microsoft YaHei;font-size:18px;">int foo( int x );

void cc( int x )

{

    foo( x );

    //...

}</span>

 

 

 

 

如果你想要在C 裡調用成員函數(包括虛函數),則需要提供一個簡單的包裝(wrapper)。例如:

 

<span style="font-family:Microsoft YaHei;font-size:18px;">// C++ code:

 

class C

 

{

 

       // ...

 

       virtual double f(int);

 

};

 

 

 

extern "C" double call_C_f(C* p, int i) // wrapper function

 

{

 

       return p->f(i);

 

}</span>

然後,你就可以這樣調用C::f():

 

<span style="font-family:Microsoft YaHei;font-size:18px;">/* C code: */

 

double call_C_f(struct C* p, int i);

 

 

 

void ccc(struct C* p, int i)

 

{

 

       double d = call_C_f(p,i);

 

       /* ... */

 

} </span>

 

 

 

 

 

 

如果你想在C 裡調用重載函數,則必須提供不同名字的包裝,這樣才能被C 代碼調用。例如:

 

<span style="font-family:Microsoft YaHei;font-size:18px;">// C++ code:

 

void f(int);

 

void f(double);

 

 

 

extern "C" void f_i(int i) { f(i); }

 

extern "C" void f_d(double d) { f(d); } </span>

然後,你可以這樣使用每個重載的f():

 

 

<span style="font-family:Microsoft YaHei;font-size:18px;">/* C code: */

 

void f_i(int);

 

void f_d(double);

 

 

 

void cccc(int i,double d)

 

{

 

       f_i(i);

 

       f_d(d);

 

       /* ... */

 

} </span>

 

 

 

 

 

參考文獻:

 

Bjarne Stroustrup的原文鏈接地址是http://www.research.att.com/~bs/bs_faq2.html#callCpp

 

 

 

 

 

 

 

下面就一個例子,來介紹一下C調用C++的過程:

 

<span style="font-family:Microsoft YaHei;font-size:18px;">// cpp.h

#ifndef  __cpp_h__

#define  __cpp_h__

 

class  class1 {

    class1();

    ~class1();

public:

    int  I;

    int  J;

 

    int  getI(void);

};

 

#endif

// end file

 

// cpp.cpp

#i nclude "stdafx.h"

#i nclude  <iostream>

#i nclude  "cpp.h"

#i nclude  "c.h"

 

using namespace  std;       // 打開標准庫名字空間

 

class1::class1()

{}

 

class1::~class1()

{}

 

int  class1::getI(void)

{

    return  I++;

}

 

// 按C 調用方式編譯下面函數

extern "C"

int  get_class1_I(struct1 * p)

{

    class1 * pClass1 = (class1 *)p;

 

    cout << "c++: " << pClass1->getI() << endl;

 

    return  pClass1->getI();

}

 

// end file

 

// c.h

#ifndef  __c_h__

#define  __c_h__

 

#ifdef  __cplusplus

extern "C" {

#endif

 

    typedef struct {

        int  i;             // 與class1 類中變量一致

  int  j;

    }struct1;

 

#ifdef  __cplusplus

}

#endif

#endif

// end file

 

// c.c

#i nclude  <cstdio>

#i nclude  "c.h"

 

extern  int  get_class1_I(void * p);

 

struct1  s;

 

int  main(void)

{

    printf ("c: %d\n", get_class1_I(&s));

    printf ("c: %d\n", get_class1_I(&s));

 

    return 0;

}

 

// end file</span>在linux下,執行:

 

gcc -c c.c

g++ -c cpp.cpp

gcc -lstdc++ c.o cpp.o -o result

 

  1. 上一頁:
  2. 下一頁:
Copyright © 程式師世界 All Rights Reserved