最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

C和C++如何實(shí)現(xiàn)互相調(diào)用詳解

 更新時(shí)間:2023年01月10日 09:39:34   作者:卍一十二畫(huà)卍  
在學(xué)習(xí)c++中用到一些古老的c語(yǔ)言庫(kù)時(shí),在工作中我們經(jīng)常要使用C和C++混合編程,下面這篇文章主要給大家介紹了關(guān)于C和C++如何實(shí)現(xiàn)互相調(diào)用的相關(guān)資料,文中通過(guò)實(shí)例代碼介紹的非常詳細(xì),需要的朋友可以參考下

前言

在項(xiàng)目開(kāi)發(fā)過(guò)程中,我們底層代碼經(jīng)常用C來(lái)實(shí)現(xiàn),而上層應(yīng)用大都會(huì)用C++實(shí)現(xiàn),這樣我們就涉及到了C和C++相互調(diào)用的情況了。那么,C/C++如何實(shí)現(xiàn)相互調(diào)用呢?

1、為什么會(huì)有差異?

  • 編譯方式不同C文件常采用gcc編譯,而Cpp文件常采用g++來(lái)編譯C++
  • 支持函數(shù)重載:由于這一特性,C++C中的同一個(gè)函數(shù),經(jīng)過(guò)編譯后,生成的函數(shù)名稱(chēng)是不同的。

這樣就導(dǎo)致了CC++之間不能直接進(jìn)行調(diào)用,要解決這一問(wèn)題,就得靠extern "C"來(lái)輔助了。

2、extern “C”

  • extern

extern關(guān)鍵字我們并不陌生,它是編程語(yǔ)言中的一種屬性,用來(lái)表示變量,函數(shù)等類(lèi)型的作用范圍。

我們經(jīng)常在.c源文件中定義變量或者實(shí)現(xiàn)函數(shù),在.h頭文件中使用extern關(guān)鍵字進(jìn)行聲明,方便其他文件調(diào)用。

“C”

編程語(yǔ)言種類(lèi)繁多,不同語(yǔ)言有不同的編譯規(guī)則,如果想要互相調(diào)用,必須告訴編譯器以什么規(guī)則去編譯文件,這樣才能正常調(diào)用。

其主要作用是:把“C”當(dāng)作一個(gè)標(biāo)志位,告訴編譯器,下面代碼以C的方式編譯!

了解其中原理后,我們來(lái)實(shí)操一下!

3、C++調(diào)用C

我們創(chuàng)建3個(gè)文件,分別為main.cpp、cal.ccal.h。

image-20221219154545328

我們分別使用gccg++單獨(dú)編譯文件,編譯出cal.omain.o兩個(gè)中間文件,很簡(jiǎn)單,定義了一個(gè)embedded_art的函數(shù)。

# dong @ ubuntu in ~/WorkSpace/Donge_Programs/Unix_Programming_Learning/c_c++_call_test on git:main x [15:57:32] 
$ ls
cal.c  cal.h  main.cpp

# dong @ ubuntu in ~/WorkSpace/Donge_Programs/Unix_Programming_Learning/c_c++_call_test on git:main x [15:57:43] 
$ gcc -c cal.c 

# dong @ ubuntu in ~/WorkSpace/Donge_Programs/Unix_Programming_Learning/c_c++_call_test on git:main x [15:57:49] 
$ g++ -c main.cpp 

# dong @ ubuntu in ~/WorkSpace/Donge_Programs/Unix_Programming_Learning/c_c++_call_test on git:main x [15:57:55] 
$ ls
cal.c  cal.h  cal.o  main.cpp  main.o

下面看一下編譯之后的中間文件cal.omain.o的符號(hào)表,看看同一個(gè)函數(shù)embedded_art不同編譯方式之后的差別。

image-20221219160137798

可以看到,g++編譯之后,對(duì)函數(shù)名稱(chēng)進(jìn)行了加工,按照自身的編譯規(guī)則,最終生成了一個(gè)新的函數(shù)名,所以我們?nèi)绻苯诱{(diào)用cal.c中的embedded_art肯定是不行的。

正確方式

使用extern "C"來(lái)使g++編譯器用C的方式編譯。

main.cpp文件中,我們引入cal.h的位置,添加extern "C"

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

再次進(jìn)行編譯,即可!

image-20221219161410964

可以看到符號(hào)表中,該函數(shù)名稱(chēng)正常,然后我們將中間文件鏈接起來(lái),執(zhí)行,輸出正確結(jié)果!

# dong @ ubuntu in ~/WorkSpace/Donge_Programs/Unix_Programming_Learning/c_c++_call_test on git:main x [16:18:36] 
$ g++ main.o cal.o 

# dong @ ubuntu in ~/WorkSpace/Donge_Programs/Unix_Programming_Learning/c_c++_call_test on git:main x [16:19:54] 
$ ls
a.out  cal.c  cal.h  cal.o  main.cpp  main.o

# dong @ ubuntu in ~/WorkSpace/Donge_Programs/Unix_Programming_Learning/c_c++_call_test on git:main x [16:19:57] 
$ ./a.out 
main entry
嵌入式藝術(shù)

4、C調(diào)用C++

我們創(chuàng)建3個(gè)文件,分別為main.c、cal.cpp、cal.h

image-20221219162526678

我們分別使用gccg++單獨(dú)編譯文件,編譯出cal.omain.o兩個(gè)中間文件,很簡(jiǎn)單,同樣定義了一個(gè)embedded_art的函數(shù)。

# dong @ ubuntu in ~/WorkSpace/Donge_Programs/Unix_Programming_Learning/c_c++_call_test/c_call_c++ on git:main x [16:24:45] 
$ g++ -c cal.cpp   

# dong @ ubuntu in ~/WorkSpace/Donge_Programs/Unix_Programming_Learning/c_c++_call_test/c_call_c++ on git:main x [16:24:52] 
$ gcc -c main.c    

# dong @ ubuntu in ~/WorkSpace/Donge_Programs/Unix_Programming_Learning/c_c++_call_test/c_call_c++ on git:main x [16:24:56] 
$ ls
cal.cpp  cal.h  cal.o  main.c  main.o

下面看一下編譯之后的中間文件cal.omain.o的符號(hào)表,看看同一個(gè)函數(shù)embedded_art不同編譯方式之后的差別。

image-20221219162704004

同樣,不同的編譯器處理方式不同,函數(shù)名稱(chēng)依舊不同!同樣,需要加入extern "C"來(lái)告訴編譯器按C的方式編譯。

我們?cè)?code>cal.h的聲明部分添加,然后重新編譯!

extern "C" {
extern void embedded_art(void);
}

image-20221219163014548

可以看到符號(hào)表中,該函數(shù)名稱(chēng)正常,然后我們將中間文件鏈接起來(lái)。

image-20221219163536166

這個(gè)時(shí)候,會(huì)出現(xiàn)報(bào)錯(cuò)extern "C",這是什么情況?

main.c文件中,引入了c++的頭文件cal.h,因?yàn)?code>"C"在C++編譯的時(shí)候才能識(shí)別,C語(yǔ)言中并沒(méi)有這個(gè)關(guān)鍵字。

所以,我們需要在g++編譯的時(shí)候去加入extern "C",而gcc編譯的時(shí)候跳過(guò),這個(gè)時(shí)候就要提到c++編譯時(shí)候的特定宏__cplusplus了,相當(dāng)于一個(gè)閥門(mén)了。

我們修改cal.h文件

#ifdef __cplusplus
extern "C" {
#endif

extern void embedded_art(void);

#ifdef __cplusplus
}
#endif

這樣就確保了,c++編譯embedded_art函數(shù)的時(shí)候,采用C語(yǔ)法編譯,而gcc編譯的時(shí)候,不作處理。

再次鏈接,執(zhí)行!

# dong @ ubuntu in ~/WorkSpace/Donge_Programs/Unix_Programming_Learning/c_c++_call_test/c_call_c++ on git:main x [16:45:06] C:1
$ gcc -no-pie cal.o main.o -o main

# dong @ ubuntu in ~/WorkSpace/Donge_Programs/Unix_Programming_Learning/c_c++_call_test/c_call_c++ on git:main x [16:46:46] 
$ ls
cal.cpp  cal.h  cal.o  main  main.c  main.o

# dong @ ubuntu in ~/WorkSpace/Donge_Programs/Unix_Programming_Learning/c_c++_call_test/c_call_c++ on git:main x [16:49:01] 
$ ./main
main entry
嵌入式藝術(shù)

補(bǔ)充:C/C++文件之間函數(shù)的引用

C通過(guò)加"中間層"來(lái)引用C++(不用修改原C++文件)

//C文件
 
int MyMax(int, int);
 
int main()
{
	int a = 10;
	int b = 20;
 
	printf("%d\n", MyMax(a,b));
 
	return 0;
}
//C++文件
int Max(int a, int b)
{
	return a > b ? a : b;
}
//中間層//C++文件
 
int Max(int ,int);
 
extern "C"
{
	int MyMax(int a, int b)
	{
		return Max(a, b);
	}
}

關(guān)鍵點(diǎn):本文件之間的函數(shù)調(diào)用,不牽扯到函數(shù)符號(hào)的生成。比如中間層那個(gè)文件:C++格式的聲明,C的引用(return Max(a,b)),不會(huì)牽扯到什么鏈接失敗,那是發(fā)生在編譯期間的,不牽扯到符號(hào)之間的解析。

總結(jié)

C/C++之間的相互調(diào)用,歸根到底就是:不同的語(yǔ)言有不同的編譯規(guī)則,要想實(shí)現(xiàn)通用,就必須告訴編譯器,按照目標(biāo)語(yǔ)言的規(guī)則進(jìn)行編譯!

到此這篇關(guān)于C和C++如何實(shí)現(xiàn)互相調(diào)用的文章就介紹到這了,更多相關(guān)C和C++互相調(diào)用內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!

相關(guān)文章

  • C語(yǔ)言之實(shí)現(xiàn)字符串小寫(xiě)變大寫(xiě)的實(shí)例

    C語(yǔ)言之實(shí)現(xiàn)字符串小寫(xiě)變大寫(xiě)的實(shí)例

    這篇文章主要介紹了C語(yǔ)言之實(shí)現(xiàn)字符串小寫(xiě)變大寫(xiě)的實(shí)例的相關(guān)資料,需要的朋友可以參考下
    2017-05-05
  • Visual Studio Code運(yùn)行程序時(shí)輸出中文成亂碼問(wèn)題及解決方法

    Visual Studio Code運(yùn)行程序時(shí)輸出中文成亂碼問(wèn)題及解決方法

    這篇文章主要介紹了解決Visual Studio Code運(yùn)行程序時(shí)輸出中文成亂碼問(wèn)題,本文通過(guò)圖文并茂的形式給大家介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下
    2020-03-03
  • 淺析_tmain()與main()的區(qū)別

    淺析_tmain()與main()的區(qū)別

    _tmain()是為了支持unicode所使用的main一個(gè)別名,既然是別名,應(yīng)該有宏定義過(guò)的,在哪里定義的呢?就在那個(gè)讓你困惑的<stdafx.h>里
    2013-03-03
  • C++實(shí)現(xiàn)掃雷游戲(控制臺(tái)不閃屏版)

    C++實(shí)現(xiàn)掃雷游戲(控制臺(tái)不閃屏版)

    這篇文章主要為大家詳細(xì)介紹了C++實(shí)現(xiàn)掃雷游戲,控制臺(tái)不閃屏版,文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下
    2020-03-03
  • C++制作DLL文件的方法詳解

    C++制作DLL文件的方法詳解

    本文主要介紹如何制作DLL,將代碼類(lèi)中的方法以接口的形式暴露出來(lái)給exe程序使用。會(huì)涉及類(lèi)廠(chǎng)創(chuàng)建方法實(shí)例、聲明DLL接口、.def文件的使用等,感興趣的可以了解一下
    2023-04-04
  • OpenCV實(shí)現(xiàn)圖像去噪算法的步驟詳解

    OpenCV實(shí)現(xiàn)圖像去噪算法的步驟詳解

    這篇文章主要為大家介紹了OpenCV中圖像去噪算法的原理,文中通過(guò)示例為大家詳細(xì)講解了圖像去噪算法的使用,感興趣的小伙伴可以了解一下
    2022-06-06
  • C語(yǔ)言實(shí)現(xiàn)簡(jiǎn)單的貪吃蛇游戲

    C語(yǔ)言實(shí)現(xiàn)簡(jiǎn)單的貪吃蛇游戲

    這篇文章主要為大家詳細(xì)介紹了C語(yǔ)言實(shí)現(xiàn)簡(jiǎn)單的貪吃蛇游戲,文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下
    2021-07-07
  • C語(yǔ)言 map函數(shù)的基礎(chǔ)用法詳解

    C語(yǔ)言 map函數(shù)的基礎(chǔ)用法詳解

    這篇文章主要為大家介紹了C語(yǔ)言 map函數(shù)的基礎(chǔ)用法,具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下,希望能夠給你帶來(lái)幫助
    2022-01-01
  • C語(yǔ)言實(shí)現(xiàn)簡(jiǎn)易的三子棋小游戲

    C語(yǔ)言實(shí)現(xiàn)簡(jiǎn)易的三子棋小游戲

    這篇文章主要為大家詳細(xì)介紹了C語(yǔ)言實(shí)現(xiàn)簡(jiǎn)易的三子棋小游戲,文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下
    2022-08-08
  • C語(yǔ)言規(guī)避野指針的方法流程

    C語(yǔ)言規(guī)避野指針的方法流程

    野指針就是指針指向的不是一個(gè)有效(合法)的地址,在程序中,如果訪(fǎng)問(wèn)野指針,可能會(huì)造成程序的崩潰,這篇文章主要介紹了C語(yǔ)言如何規(guī)避野指針,需要的朋友可以參考下
    2024-03-03

最新評(píng)論

长阳| 泗阳县| 大厂| 仙居县| 兴文县| 靖远县| 六安市| 双城市| 龙口市| 尉氏县| 新巴尔虎左旗| 安龙县| 阜宁县| 乌恰县| 耿马| 长寿区| 长丰县| 康马县| 葫芦岛市| 大厂| 新化县| 伊金霍洛旗| 平顺县| 南丹县| 尚义县| 桦南县| 保靖县| 盐亭县| 游戏| 雷州市| 广元市| 类乌齐县| 岱山县| 岳阳县| 定州市| 乌拉特前旗| 尉氏县| 舟山市| 房产| 临邑县| 锦州市|