C和C++混合編程問(wèn)題
分析以下一段代碼:
/*=======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; }
調(diào)用以上三個(gè)文件,編譯通過(guò),但是執(zhí)行是出現(xiàn)以下問(wèn)題:
obj : error LNK2001: 無(wú)法解析的外部符號(hào) "int __cdecl sum(int,int)" (?sum@@YAHHH@Z)
E:\Programming\Grapic\test\Debug\test.exe : fatal error LNK1120: 1 個(gè)無(wú)法解析的外部命令
問(wèn)題出在哪里呢? 在main.cpp里調(diào)用了sum.c,也就是說(shuō)在C++程序里調(diào)用了C程序,此時(shí)如果沒(méi)有作相應(yīng)處理將會(huì)出現(xiàn)鏈接錯(cuò)誤。
extern "C"表示編譯生成的內(nèi)部符號(hào)名使用C約定。C++支持函數(shù)重載,而C不支持,兩者的編譯規(guī)則也不一樣。函數(shù)被C++編譯后在符號(hào)庫(kù)中的名字與C語(yǔ)言的不同。例如,假設(shè)某個(gè)函數(shù)的原型為:void foo( int x, int y ); 該函數(shù)被C編譯器編譯后在符號(hào)庫(kù)中的名字可能為_(kāi)foo,而C++編譯器則會(huì)產(chǎn)生像_foo_int_int之類的名字(不同的編譯器可能生成的名字不同,但是都采用了相同的機(jī)制,生成的新名字稱為“mangled name”)。_foo_int_int這樣的名字包含了函數(shù)名、函數(shù)參數(shù)數(shù)量及類型信息,C++就是靠這種機(jī)制來(lái)實(shí)現(xiàn)函數(shù)重載的。
那么如果在C中調(diào)用C++代碼,以及如何在C++中調(diào)用C的代碼呢?
extern "C"表示編譯生成的內(nèi)部符號(hào)名使用C約定。
1. 如何在C++中調(diào)用C呢?
C++調(diào)用C,extern "C" 的作用是:讓C++連接器找調(diào)用函數(shù)的符號(hào)時(shí)采用C的方式
本文開(kāi)頭提出的筆試題可以這樣修改:
/*=======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; }
執(zhí)行成功
相信到這里差不多明白了
2. 怎樣在C里調(diào)用C++呢?
在C中引用C++函數(shù)(C調(diào)用C++,使用extern "C"則是告訴編譯器把cpp文件中extern "C"定義的函數(shù)依照C的方式來(lái)編譯封裝接口,當(dāng)然接口函數(shù)里面的C++語(yǔ)法還是按C++方式編譯)
執(zhí)行:test1.obj : error LNK2019: 無(wú)法解析的外部符號(hào) _sum,該符號(hào)在函數(shù) _main 中被引用
E:\Programming\Grapic\test\Debug\test.exe : fatal error LNK1120: 1 個(gè)無(wú)法解析的外部命令
/*=======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. 標(biāo)準(zhǔn)規(guī)范寫(xiě)法
一般我們都將函數(shù)聲明放在頭文件,當(dāng)我們的函數(shù)有可能被C或C++使用時(shí),我們無(wú)法確定被誰(shuí)調(diào)用,使得不能確定是否要將函數(shù)聲明在extern "C"里,所以,我們可以添加
#ifdef __cplusplus extern "C" { #endif //函數(shù)聲明 #ifdef __cplusplus } #endif
利用以上聲明形式就可以綜合運(yùn)用了。
在C中引用C++語(yǔ)言中的函數(shù)和變量時(shí),C++的函數(shù)或變量要聲明在extern "C"{}里,但是在C語(yǔ)言中不能使用extern "C",否則編譯出錯(cuò)。(出現(xiàn)錯(cuò)誤: error C2059: syntax error : 'string',這個(gè)錯(cuò)誤在網(wǎng)上找了很久,國(guó)內(nèi)網(wǎng)站沒(méi)有搜到直接說(shuō)明原因的,原因是extern "C"是C++中的關(guān)鍵詞,不是C的,所有會(huì)出錯(cuò)。
/*=======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; }
相關(guān)文章
C語(yǔ)言使用普通循環(huán)方法和遞歸求斐波那契序列示例代碼
這篇文章主要介紹了C語(yǔ)言使用普通循環(huán)方法和遞歸求斐波那契序列示例代碼,大家參考使用吧2013-11-11C/C++詳解實(shí)現(xiàn)二層轉(zhuǎn)發(fā)
數(shù)據(jù)鏈路層是開(kāi)放系統(tǒng)互連 (OSI) 模型中的第二層,該層用于通過(guò) LAN 等單一網(wǎng)絡(luò)進(jìn)行通信的節(jié)點(diǎn),第二層數(shù)據(jù)包不能從一個(gè)網(wǎng)絡(luò)傳輸?shù)搅硪粋€(gè)網(wǎng)絡(luò)。而二層轉(zhuǎn)發(fā)是根據(jù)報(bào)文的目的MAC直接進(jìn)行轉(zhuǎn)發(fā),轉(zhuǎn)發(fā)過(guò)程中不用對(duì)報(bào)文的頭部做任何的修改2022-05-05Qt實(shí)現(xiàn)抽獎(jiǎng)小游戲的三種方式
本文主要介紹了Qt實(shí)現(xiàn)抽獎(jiǎng)小游戲的三種方式,主要包括while循環(huán),定時(shí)器,線程這三種方法,具有一定的參考價(jià)值,感興趣的可以了解一下2023-10-10生成隨機(jī)數(shù)rand函數(shù)的用法詳解
本篇文章是對(duì)生成隨機(jī)數(shù)rand函數(shù)的用法進(jìn)行了詳細(xì)的分析介紹,需要的朋友參考下2013-05-05C語(yǔ)言實(shí)現(xiàn)動(dòng)態(tài)版通訊錄的代碼分享
這篇文章主要為大家詳細(xì)介紹了如何利用C語(yǔ)言實(shí)現(xiàn)一個(gè)簡(jiǎn)單的動(dòng)態(tài)版通訊錄,主要運(yùn)用了結(jié)構(gòu)體,一維數(shù)組,函數(shù),分支與循環(huán)語(yǔ)句等等知識(shí),需要的可以參考一下2023-01-01C語(yǔ)言中qsort函數(shù)的用法實(shí)例詳解
這篇文章主要介紹了C語(yǔ)言中qsort函數(shù)的用法實(shí)例詳解的相關(guān)資料,希望通過(guò)本文能幫助到大家,讓大家理解掌握這部分內(nèi)容,需要的朋友可以參考下2017-10-10C語(yǔ)言實(shí)現(xiàn)手寫(xiě)Map(數(shù)組+鏈表+紅黑樹(shù))的示例代碼
這篇文章主要為大家詳細(xì)介紹了如何利用C語(yǔ)言實(shí)現(xiàn)手寫(xiě)Map(數(shù)組+鏈表+紅黑樹(shù)),文中的示例代碼講解詳細(xì),對(duì)我們學(xué)習(xí)有一定借鑒價(jià)值,需要的可以參考一下2022-09-09