深刻理解C/C++混合編程

本篇資料問轉載,內容是C++和C語言混合編程,可是實際操做中和資料部份內容有所出入,必要地方已經加上註釋。ios

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

1、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」修飾。

2、extern「C」__cplusplusspa

#ifdef __cplusplus
       extern "C" {
       #endif
       #ifdef __cplusplus
       }
       #endif
    CplusplusC plus plus"C++"用於C++文檔的頭文件中,上面代碼的意思是:若是是C++文件(*.cpp)後綴,則使用extern 「C」,在C++項目中應用的很是普遍。即便用gcc編譯器編譯,函數名爲C類型如_foo。我的認爲,搞懂了這兩個關鍵字,尤爲是理解extern "C"(再次強調,不爲過,呵呵),接下來的混合編程也就差很少了,哈哈哈。。。。.net

3、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

4、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"{         //本人親自實驗中,用C++程序調用C不加extern "C"編譯運行經過,加上反而報錯,特在次註釋14/04/29
#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++混合編程的問題,能夠聯繫我哦.

//原文的最後一段有些很差理解,意思也就是gcc編譯器作鏈接的時候默認會自動加載一些庫文件,可是不包括stdc++這個庫,因此用gcc鏈接C++模塊的時候要在命令行顯式加載stdc++這個庫(-lstdc++)



原文連接   http://www.jb51.net/article/37386.htm

相關文章
相關標籤/搜索