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

來源:互聯網
上載者:User

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

一、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 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.cpp:C++檔案

[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.c:C檔案

[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++混合編程的問題,可以聯絡我哦.

相關文章

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.