C/C++混合編程

    在工作中,CC++密不可分,做我們嵌入式方面的,當然更多的是C,但,有時候卻少不了C++,而且是CC++混搭(混合編程)在一起的,比如,RTP視頻傳輸,live555多媒體播放等都是C++下的,他需要調用JRTPLIB庫,再比如,我那郵件發送,我也用C++寫的,定義了一個Email對象,包含了成員:收發郵件地址,用戶名,密碼等,以及方法:郵件頭、Base64編碼和郵件發送這些操作,很好用,所以,很多時候,C++還是蠻不錯的。。。。但,*.c*.cpp文件混搭在一起,不是那麼的簡單,知識總是:用時方恨少啊!!!現在,我們就來慢慢的瞭解吧。大笑

 

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

    1. extern "C"的真實目的是實現類CC++的混合編程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類型的;externC/C++語言中表明函數和全局變量作用範圍(可見性)的關鍵字,該關鍵字告訴編譯器,其聲明的函數和變量可以在本模塊或其它模塊中使用。被extern "C"修飾的變量和函數是按照C語言方式編譯和連接的。   

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

 

二、extern“C”__cplusplus

#ifdef __cplusplus

       extern "C" {

       #endif

 

       #ifdef __cplusplus

       }

       #endif

    CplusplusC plus plus"C++"用於C++文檔的頭文件中,上面代碼的意思是:如果是C++文件(*.cpp)後綴,則使用extern “C”,在C++項目中應用的非常廣泛。即使用gcc編譯器編譯,函數名爲C類型如_foo。個人認爲,搞懂了這兩個關鍵字,尤其是理解extern "C"(再次強調,不爲過,呵呵),接下來的混合編程也就差不多了,哈哈哈。。。。偷笑

 

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

1.設計程序,共四個文件

animal.cpp animal.h  main.c Makefile

1.1 animal.h

[root@localhost CC++]#cat animal.h

#ifndef __ANIMAL_H__  //防止被重複包含

#define __ANIMAL_H__

#ifdef __cplusplus

extern "C" {

#endif

class ANIMAL{

public:

        ANIMAL(char* );

        ~ANIMAL();

        char* getname(void);

private:

        char* name;

};

void print(void);

#ifdef __cplusplus

}

#endif

#endif  // __ANIMAL_H__

 

1.2 animal.cppC++文件

[root@localhost CC++]#cat animal.cpp

#include "animal.h"

#include <iostream>

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;

}

void print(void) //對外接口,而且必須有一個非類中方法,才能被C調用

{

        ANIMAL animal("dog");

        char* animal_name = animal.getname();

        cout << "animal name is :" << animal_name << endl;

}

 

1.3 main.cC文件

[root@localhost CC++]#cat main.c

int main(void)

{

        print();

        return 0;

}

 

1.4 Makefile

[root@localhost CC++]#cat Makefile

main:main.c animal.o

        gcc -lstdc++ main.c animal.o -o main

animal.o:animal.h

        g++ -c animal.cpp

.PHONY : clean

clean:

        -rm animal.o main

 

2.測試

2.1生成可執行程序main

[root@localhost CC++]#make

g++ -c animal.cpp

gcc -lstdc++ main.c animal.o -o main

2.2運行可執行程序main

[root@localhost CC++]# ./main

animal name is :dog

 

四、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 <stdio.h>

#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代碼很簡單,但C調用C++接口可把我給累壞了,苦啊。就是這個gcc後面跟的-lstdc++害的哭,出現undefined reference to `__gxx_personality_v0'這個錯誤。是因爲你用gcc編譯.cpp文件(animal.cpp.按系統默認.cpp文件是c++的文件格式。當然,混搭時,我還遇到了其他的一些問題,都是一些小問題,如果上面解釋的還不足以讓你解決C\C++混合編程的問題,可以聯繫我哦吐舌頭,哎,我總算--終於見到太陽了。

 

親們,好好享受吧微笑。。。。。。。。。。。。。。。。。。。。。。。。。。。。。

 

 

 

發佈了68 篇原創文章 · 獲贊 89 · 訪問量 53萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章