C和C++混合編程問題

來源:互聯網
上載者:User

分析以下一段代碼:

/*=======sum.h=========*/

#ifndef SUM_H
#define SUM_H
#include <stdio.h>

int sum(int a,int b);

#endif;

/*=======sum.c=========*/

#include "sum.h"

int sum(int a,int b)
{
int c=a+b;
return c;
}

/*====main.cpp======*/

#include "sum.h"

void mian(){

cout << sum(1,2)<<endl;

}

調用以上三個檔案,編譯通過,但是執行是出現以下問題:

obj : error LNK2001: 無法解析的外部符號 "int __cdecl sum(int,int)" (?sum@@YAHHH@Z)
E:\Programming\Grapic\test\Debug\test.exe : fatal error LNK1120: 1 個無法解析的外部命令

問題出在哪裡呢? 在main.cpp裡調用了sum.c,也就是說在C++程式裡調用了C程式,此時如果沒有作相應處理將會出現連結錯誤。

extern "C"表示編譯產生的內部符號名使用C約定。C++支援函數重載,而C不支援,兩者的編譯規則也不一樣。函數被C++編譯後在符號庫中的名字與C語言的不同。例如,假設某個函數的原型為:void foo( int x, int y ); 該函數被C編譯器編譯後在符號庫中的名字可能為_foo,而C++編譯器則會產生像_foo_int_int之類的名字(不同的編譯器可能產生的名字不同,但是都採用了相同的機制,產生的新名字稱為“mangled name”)。_foo_int_int這樣的名字包含了函數名、函數參數數量及類型資訊,C++就是靠這種機制來實現函數重載的。

那麼如果在C中調用C++代碼,以及如何在C++中調用C的代碼呢?

extern "C"表示編譯產生的內部符號名使用C約定。

1. 如何在C++中調用C呢?

C++調用C,extern "C" 的作用是:讓C++連接器找調用函數的符號時採用C的方式

本文開頭提出的筆試題可以這樣修改:

/*=======sum.h=========*/

#ifndef SUM_H
#define SUM_H
#include <stdio.h>

int sum(int a,int b);

#endif;

/*=======sum.c=========*/

#include "sum.h"

int sum(int a,int b)
{
int c=a+b;
return c;
}

/*====main.cpp======*/

extern "C"
{
#include "sum.h"
}

void mian(){

cout << sum(1,2)<<endl;

}

執行成功

相信到這裡差不多明白了

 

2. 怎樣在C裡調用C++呢?

    在C中引用C++函數(C調用C++,使用extern "C"則是告訴編譯器把cpp檔案中extern "C"定義的函數依照C的方式來編譯封裝介面,當然介面函數裡面的C++文法還是按C++方式編譯)

執行:test1.obj : error LNK2019: 無法解析的外部符號 _sum,該符號在函數 _main 中被引用
E:\Programming\Grapic\test\Debug\test.exe : fatal error LNK1120: 1 個無法解析的外部命令

/*=======sum.h=========*/

#ifndef SUM_H
#define SUM_H
#include <stdio.h>

int sum(int a,int b);

#endif;

/*=======sum.cpp=========*/

#include "sum.h"

extern "C"
{

int sum(int a,int b)
{
int c=a+b;
return c;
}
}

/*====main.c======*/

#include "sum.h"

void mian(){

cout << sum(1,2)<<endl;

}

3. 標準規範寫法

一般我們都將函式宣告放在標頭檔,當我們的函數有可能被C或C++使用時,我們無法確定被誰調用,使得不能確定是否要將函式宣告在extern "C"裡,所以,我們可以添加

#ifdef __cplusplus

extern "C"

{

#endif

//函式宣告

#ifdef __cplusplus

}

#endif

利用以上聲明形式就可以綜合運用了。

 

在C中引用C++語言中的函數和變數時,C++的函數或變數要聲明在extern "C"{}裡,但是在C語言中不能使用extern "C",否則編譯出錯。(出現錯誤: error C2059: syntax error : 'string',這個錯誤在網上找了很久,國內網站沒有搜到直接說明原因的,原因是extern "C"是C++中的關鍵詞,不是C的,所有會出錯。

 

/*=======sum.h=========*/

#ifndef SUM_H
#define SUM_H
#include <stdio.h>

int sum(int a,int b);

#endif;

/*=======sum.cpp=========*/

#include "sum.h"

int sum(int a,int b)
{
int c=a+b;
return c;
}

/*====main.c======*/

#include "sum.h"

void mian(){

cout << sum(1,2)<<endl;

}

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在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.