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

C代碼中如何調用C++ C++中如何調用C

編輯:C++入門知識

C代碼中如何調用C++ C++中如何調用C


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

包裝(wrapper)

2. 在C中調用C++:extern C 的作用是:讓C++連接器找調用函數的符號時采用C的方式

 

注意這裡的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++方式編譯。
如:1 普通函數
// C++ Code
extern C int foo( int x );
int foo( int x )
{
//...
}
這樣,編譯器會將foo函數編譯成類似_foo符號,而不會編譯成類似_foo_int符號
則C可以這樣調用C++函數
// C Code
int foo( int x );
void cc( int x )
{
foo( x );
//...
}
2 如果想調用重載的C++函數,則須封裝單獨的接口共C調用。

// C++ Code
void foo( int x );
void foo( float x );

extern C void foo_i( int x )
{
foo( x );
}
extern C void foo_f( float x )
{
foo( x );
}搜索
則C中可這樣調用
// C Code
void foo_i( int x );
void foo_f( float x );
void ccc( int x1, float x2 )
{
foo_i( x1 );
foo_f( x2 );
// ...
}
3 C中想調用C++中的成員函數(包括虛函數),則需要提供一個簡單的包裝(wrapper)。

例如: // C++ code:

class C

{

...

virtual double f(int);

};

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

{

return p->f(i);

}

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

//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);

...

}

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

http://blog.csdn.net/caspiansea/article/details/9676153


而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

//一段代碼

#ifdef __cplusplus } #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 {

#include f.h

}

 

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