在實際工作中可能經常要進行C和C++的混合編程,C++調用C語言的代碼通常都比較容易,但也有一些細節需要注意。C要調用C++的代碼就略為麻煩一些,因為C不支持面向對象的特征。
首先我們來看一下C++調用C語言的代碼。要讓你的C代碼既能被C代碼又能被C++調用雖說容易,但是還是有需要注意的地方。現有三個文件分別如下:
/* file TestC.h */
#ifndef TESTC_H
#define TESTC_H
 
#ifdef __cplusplus
extern "C" {
#endif
 
int add(int a, int b);
      
#ifdef __cplusplus
}
#endif
 
#endif /* TESTC_H */
 
 
/* file TestC.c */
 
#include "TestC.h"
 
int add(int a, int b)
{
    return (a + b);
}
 
 
/* file TestCpp.cpp */
#include "stdio.h"
#include "TestC.h"
 
int main()
{
       printf("add = %d\n", add(2, 5));
      
       return 0;
}
說明:
file TestC.h是C的頭文件,file TestC.c是其實現文件,file TestCpp.cpp是調用C函數的C++文件。
文件TestC.h中的TESTC_H定義是為了頭文件保護,” #ifdef __cplusplus”這個不能缺少,你可以去查看C的標準庫頭文件中都有這個,如”stdio.h”。有了這個宏編譯器就知道現在是C還是C++在調用它。
為什么要區分C與C++調用呢?其深層次原因是因為C和C++編譯器在編譯和鏈接時對于函數的處理不一樣。C++為了支持函數重載在編譯時會加入函數參數及類型信息。如上面的add方法,C編譯器編譯后在符號庫中的名字為_add,而C++編譯器則會產生像_add_int_int之類的名字。C++正是依靠這種機制實現了函數的重載。
extern關鍵字表示將函數或變量聲明為全局類型,與之相對應的是static。static限定函數或變量的作用域為本文件。extern還有一個作用就是與”C”連在一起使用,即extern “C”通知編譯器將extern “C”所包含的代碼按照C的方式編譯和鏈接。
 
下面我們就來看看如何在C語言中使用C++的代碼(包括C++類的方法)。為了簡單起見,我將類的定義和實現放在一個文件中(通常應該是將分別放在.h和.cpp文件中)。自定義類文件(這里省略了頭文件保護等其它細節)如下:
//* file TestClass.h */
 
class HJH
{
public:
    int add(int a, int b)
       {
              return (a + b);
       }
};
 
將C++類封裝為C函數的文件(為了簡略也將聲明和實現放在了同一個文件中)如下:
/* file TestCpp.cpp */
 
#include "TestClass.h"
 
extern "C" int add_cpp(int a, int b);
 
int add_cpp(int a, int b)
{
       HJH hjh;
 
       return hjh.add(a, b);      
}
 
實際調用C++代碼的C文件如下:
/*file TestC.c */
#include "stdio.h"
 
extern int add_cpp(int a, int b);
 
int main()
{
       printf("add_cpp = %d\n", add_cpp(2, 5));
      
       return 0;
}
上面的過程很清晰,就是用一個函數將C++類的使用封裝起來,然后將它外部聲明為C函數就可以了。
文件TestClass.h定義并實現了一個類,該類只有一個add方法。文件TestCpp.cpp定義并實現了一個函數add_cpp,函數中定義了一個HJH類對象并調用了該對象的add方法。然后將add_cpp函數進行外部聲明為C。
TestC.c文件中為了使用add_cpp函數,也需要進行外部聲明。這是為了通知編譯器說明這個函數是在其他文件中實現(注意在C文件中的extern后面不可加”C”)。當這三個文件一起編譯鏈接時,編譯器就可以找到add_cpp的具體實現。

本文來自CSDN博客,轉載請標明出處:http://blog.csdn.net/gobitan/archive/2007/03/18/1532769.aspx