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

C&C++混合編程

編輯:C++入門知識

首先,混合編程不是指在同一個文件裡寫C與C++。

混合編程包括:1,C++引用C的頭文件;2,g++生成的.o與gcc生成的.o相鏈接。

一、extern“C”的作用(最重點)

1. extern "C"的真實目的是實現類C和C++的混合編程。extern “C”是由C++提供的一個連接交換指定符號,用於告訴C++這段代碼是C函數。extern “C”後面的函數不使用的C++的名字修飾,而是用C。這是因為C++編譯後庫中函數名會變得很長,與C生成的不一致,造成C++不能直接調用C函數。

2.C++語言支持函數重載,C語言不支持函數重載。函數被C++編譯後在庫中的名字與C語言的不同。假設某個函數的原型為:void foo(int x, int y);該函數被C編譯器編譯後在庫中的名字為_foo,而C++編譯器則會產生像_foo_int_int之類的名字。C++提供了C連接交換指定符號extern“C”來解決名字匹配問題。

3.被extern "C"限定的函數或變量是extern類型的;extern是C/C++語言中表明函數和全局變量作用范圍(可見性)的關鍵字,該關鍵字告訴編譯器,其聲明的函數和變量可以在本模塊或其它模塊中使用。被extern "C"修飾的變量和函數是按照C語言方式編譯和連接的。

4.與extern對應的關鍵字是static,被它修飾的全局變量和函數只能在本模塊中使用。因此,一個函數或變量只可能被本模塊使用時,其不可能被extern “C”修飾。

二、extern“C”與__cplusplus

#ifdef __cplusplus
       extern "C" {
       #endif
       #ifdef __cplusplus
       }
       #endif

_cplusplus標示符用來判斷程序是用c還是c++編譯程序編譯的。當編譯c++程序時,這個標示符會被定義,編譯c程序時,不會定義。於C++文檔的頭文件中,上面代碼的意思是:如果是C++文件(*.cpp)後綴,則使用extern “C”,在C++項目中應用的非常廣泛。

三、C調用C++函數(接口)

1. cpp頭文件:animal.h

#ifndef __ANIMAL_H__  //防止被重復包含
#define __ANIMAL_H__
class ANIMAL{
public:
        ANIMAL(char* );
        ~ANIMAL();
        char* getname(void);
private:
        char* name;
};
#endif  // __ANIMAL_H__ 

2. cpp文件:animal.cpp

#include "animal.h"
#include 
#include 
using namespace std;
ANIMAL::ANIMAL(char* data)//構造函數
{    name = new char[64];
        strcpy(name, data);
}
ANIMAL::~ANIMAL() //析構函數
{
       if(name)
      {
        delete[] name;
        name = NULL;
      }
}
char* ANIMAL::getname(void)
{        
    return name;
}

3. 中間層cpp頭文件:middle.h

#ifndef __MIDDLE_H__
#define __MIDDLE_H__
 
#ifdef __cplusplus
extern "C"
{
#endif
void print(void);
 
#ifdef __cplusplus
}
#endif
 
#endif

注:middle.h需要包含在.C文件中,因此middle.h中不能包含含有C++關鍵字(如class)的animal.h.

4. 中間層cpp文件:middle.cpp

#include "middle.h"
#include "animal.h"
 
#include 
using namespace std;
void print(void) //對外接口
{
        ANIMAL animal("dog");
        char* animal_name = animal.getname();
        cout << "animal name is :" << animal_name << endl;
}

注:接口函數需要用到C++中的class,因此需要包含animal.h.

5. C文件:test.c

#include "middle.h"
int main(int argc, char *argv[])
{
print();
return 0;
}

6. Makefile

main: test.o animal.o middle.o

gcc -o test middle.o animal.o test.o -lstdc++

animal.o:animal.h

g++ -c animal.cpp

middle.o:middle.h

g++ -c middle.cpp

clean:

rm -f middle.o animal.o test test.o

說明:

(1) 在.C文件中包含的直接或間接頭文件中不要有c++關鍵字,因為.C文件是c編譯器編譯的,無法識別C++關鍵字。

(2) .c文件要想使用cpp中的class,需要在一個非成員函數中,而這個非成員函數是在cpp文件中實現的(.c文件不識別class)。

(3) gcc連接時需要加上-lstdc++(使用c++庫),因為默認會使用c動態庫,而c庫中沒有c++的一些函數。

整個上述例子的關系可用圖形表示為:

\

<喎?http://www.Bkjia.com/kf/ware/vc/" target="_blank" class="keylink">vcD4KPHA+wszJq6O6sdjQ69PDYyYjNDM7JiM0Mzux4NLro6zSqsO0ysdjcHDOxLz+o6zSqsO0uqzT0GNsYXNzudi8/NfWPC9wPgo8cD7Atsmro7pjzsS8/jwvcD4KPHA+s8jJq6O61tC85M/OvdPNt87EvP6jqNPrYyYjNDM7JiM0MzvO3rnYo6k8L3A+CjxwPteio7pDtffTw0MmIzQzOyYjNDM7u7nT0NK71taw/Ln8uq/K/beooaM8L3A+CjxwPrLiytSjujwvcD4KPHA+IDxpbWcgc3JjPQ=="http://www.2cto.com/uploadfile/Collfiles/20140410/2014041010070517.png" alt="\">

四、C++調用C函數

應該這個比較簡單,我就不多寫了,就直接寫代碼。

共有三個文件:1.h 1.c main.cpp

[root@localhost aa]#cat 1.h

#ifndef _1__H_

#define _1__H_

extern void print(char* );

#endif

[root@localhost aa]#cat 1.c

#include

#include "1.h"

void print(char* data)

{

printf("%s\n", data);

}

[root@localhost aa]#cat main.cpp

extern "C"{

#include "1.h"}

int main(void)

{

print(“hello,world\n”);

return 0;

}

gcc –c 1.c

g++ main.cpp 1.o

接著./a.out,又可以出現我們神奇的hello,world了,C++調用C代碼很簡單。

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