在項目開發過程中,我們底層代碼經常用C來實現,而上層應用大都會用C++實現,這樣我們就涉及到了C和C++相互調用的情況了。那么,C/C++如何實現相互調用呢?
1、為什么會有差異?
1)編譯方式不同:C文件常采用gcc編譯,而Cpp文件常采用g++來編譯2)C++支持函數重載:由于這一特性,C++和C中的同一個函數,經過編譯后,生成的函數名稱是不同的。
這樣就導致了C與C++之間不能直接進行調用,要解決這一問題,就得靠extern "C"來輔助了。2、extern "C"
·externextern關鍵字我們并不陌生,它是編程語言中的一種屬性,用來表示變量,函數等類型的作用范圍。
我們經常在·"C"編程語言種類繁多,不同語言有不同的編譯規則,如果想要互相調用,必須告訴編譯器以什么規則去編譯文件,這樣才能正常調用。其主要作用是:把.c源文件中定義變量或者實現函數,在.h頭文件中使用extern關鍵字進行聲明,方便其他文件調用。
“C”當作一個標志位,告訴編譯器,下面代碼以C的方式編譯!了解其中原理后,我們來實操一下!
3、C++調用C
我們創建3個文件,分別為main.cpp、cal.c、cal.h。

gcc和g++單獨編譯文件,編譯出cal.o和main.o兩個中間文件,很簡單,定義了一個embedded_art的函數。# dong @ ubuntu in ~/WorkSpace/Donge_Programs/Unix_Programming_Learning/c_c++_call_test on git:main x [1532] $ ls cal.c cal.h main.cpp # dong @ ubuntu in ~/WorkSpace/Donge_Programs/Unix_Programming_Learning/c_c++_call_test on git:main x [1543] $ gcc -c cal.c # dong @ ubuntu in ~/WorkSpace/Donge_Programs/Unix_Programming_Learning/c_c++_call_test on git:main x [1549] $ g++ -c main.cpp # dong @ ubuntu in ~/WorkSpace/Donge_Programs/Unix_Programming_Learning/c_c++_call_test on git:main x [1555] $ ls cal.c cal.h cal.o main.cpp main.o下面看一下編譯之后的中間文件cal.o和main.o的符號表,看看同一個函數embedded_art不同編譯方式之后的差別。

g++編譯之后,對函數名稱進行了加工,按照自身的編譯規則,最終生成了一個新的函數名,所以我們如果直接調用cal.c中的embedded_art肯定是不行的。正確方式
使用extern "C"來使g++編譯器用C的方式編譯。在main.cpp文件中,我們引入cal.h的位置,添加extern "C"extern "C" { #include "cal.h" }再次進行編譯,即可!

# dong @ ubuntu in ~/WorkSpace/Donge_Programs/Unix_Programming_Learning/c_c++_call_test on git:main x [1636] $ g++ main.o cal.o # dong @ ubuntu in ~/WorkSpace/Donge_Programs/Unix_Programming_Learning/c_c++_call_test on git:main x [1654] $ 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 [1657] $ ./a.out main entry 嵌入式藝術4、C調用C++
我們創建3個文件,分別為main.c、cal.cpp、cal.h。

gcc和g++單獨編譯文件,編譯出cal.o和main.o兩個中間文件,很簡單,同樣定義了一個embedded_art的函數。# dong @ ubuntu in ~/WorkSpace/Donge_Programs/Unix_Programming_Learning/c_c++_call_test/c_call_c++ on git:main x [1645] $ g++ -c cal.cpp # dong @ ubuntu in ~/WorkSpace/Donge_Programs/Unix_Programming_Learning/c_c++_call_test/c_call_c++ on git:main x [1652] $ gcc -c main.c # dong @ ubuntu in ~/WorkSpace/Donge_Programs/Unix_Programming_Learning/c_c++_call_test/c_call_c++ on git:main x [1656] $ ls cal.cpp cal.h cal.o main.c main.o下面看一下編譯之后的中間文件cal.o和main.o的符號表,看看同一個函數embedded_art不同編譯方式之后的差別。

extern "C"來告訴編譯器按C的方式編譯。我們在cal.h的聲明部分添加,然后重新編譯!extern "C" { extern void embedded_art(void); }


extern "C",這是什么情況?在main.c文件中,引入了c++的頭文件cal.h,因為"C"在C++編譯的時候才能識別,C語言中并沒有這個關鍵字。所以,我們需要在g++編譯的時候去加入extern "C",而gcc編譯的時候跳過,這個時候就要提到c++編譯時候的特定宏__cplusplus了,相當于一個閥門了。我們修改cal.h文件:#ifdef __cplusplus extern "C" { #endif extern void embedded_art(void); #ifdef __cplusplus } #endif這樣就確保了,c++編譯embedded_art函數的時候,采用C語法編譯,而gcc編譯的時候,不作處理。再次鏈接,執行!# dong @ ubuntu in ~/WorkSpace/Donge_Programs/Unix_Programming_Learning/c_c++_call_test/c_call_c++ on git:main x [1606] 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 [1646] $ 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 [1601] $ ./main main entry 嵌入式藝術5、總結
C/C++之間的相互調用,歸根到底就是:不同的語言有不同的編譯規則,要想實現通用,就必須告訴編譯器,按照目標語言的規則進行編譯!
審核編輯 :李倩
聲明:本文內容及配圖由入駐作者撰寫或者入駐合作網站授權轉載。文章觀點僅代表作者本人,不代表電子發燒友網立場。文章及其配圖僅供工程師學習之用,如有內容侵權或者其他違規問題,請聯系本站處理。
舉報投訴
-
函數
+關注
關注
3文章
4417瀏覽量
67516 -
C++
+關注
關注
22文章
2124瀏覽量
77120 -
編譯器
+關注
關注
1文章
1672瀏覽量
51615
發布評論請先 登錄
相關推薦
熱點推薦
keil實現c與c++混合編程
參考touchgfx生成的代碼,發現了一個不需要添加--cpp11 參數的解決方法,具體操作如下。
一、創建一個空白的C文件和頭文件在頭文件中定義c++文件中需要調用的函數,如圖所示
二、在
發表于 01-26 08:58
汽車網絡安全開發語言選型指南:C/C++/Rust/Java等主流語言對比+Perforce QAC/Klocwork工具支持
汽車網絡安全如何選編程語言?C、C++、Rust、Java……誰更適合AUTOSAR、ISO/SAE 21434?一文了解8種主流語言的優劣與適用場景,以及Perforce QAC/Klocwork對MISRA、CERT等規范的支持。
C語言和C++之間的區別是什么
區別
1、面向對象編程 (OOP):
C語言是一種面向過程的語言,它強調的是通過函數將任務分解為一系列步驟進行執行。
C++在C語言的基礎上擴展了面向對象的特性,支持類(class)、封裝、繼承
發表于 12-11 06:23
C/C++條件編譯
條件編譯是一種在編譯時根據條件選擇性地包含或排除部分代碼的處理方法。在 C/C++ 中,條件編譯使用預處理指令 #ifdef、#endif、#else 和 #elif 來實現。常用的條件編譯指令有
發表于 12-05 06:21
C++程序異常的處理機制
1、什么是異常處理?
有經驗的朋友應該知道,在正常的C和C++編程過程中難免會碰到程序不按照原本設計運行的情況。
最常見的有除法分母為零,數組越界,內存分配失效、打開相應文件失敗等等。
一個程序
發表于 12-02 07:12
嵌入式C/C++回歸測試四大最佳實踐(附自動化測試工具TESSY使用教程)
嵌入式開發中,一次微小的代碼改動都可能引發“蝴蝶效應”,如何守護系統的穩健?推薦專業的自動化測試工具#TESSY,源自戴姆勒-奔馳,是嵌入式C/C++單元/集成測試的標桿。
C/C++代碼靜態測試工具Perforce QAC 2025.3的新特性
?Perforce Validate?中?QAC?項目的相對/根路徑的支持。C++?分析也得到了增強,增加了用于檢測 C++?并發問題的新檢查,并改進了實體名稱和實
技能+1!如何在樹莓派上使用C++控制GPIO?
在使用樹莓派時,你會發現Python和Scratch是許多任務(包括GPIO編程)中最常用的編程語言。但你知道嗎,你也可以使用C++進行GPIO編程,而且這樣做還有不少好處。借助WiringPi
C++ 與 Python:樹莓派上哪種語言更優?
Python是樹莓派上的首選編程語言,我們的大部分教程都使用它。然而,C++在物聯網項目中同樣廣受歡迎且功能強大。那么,在樹莓派項目中選擇哪種語言更合適呢?Python因其簡潔性、豐富的庫和資源而被
Perforce QAC產品簡介:面向C/C++的靜態代碼分析工具(已通過SO 26262認證)
Perforce QAC專為C/C++開發者打造,支持多種編碼規范、功能安全標準(ISO 26262)等,廣泛用于汽車、醫療、嵌入式開發領域,可幫助快速識別關鍵缺陷、提升代碼質量、實現合規交付。
基于LockAI視覺識別模塊:C++目標檢測
本文檔基于瑞芯微RV1106的LockAI凌智視覺識別模塊,通過C++語言做的目標檢測實驗。本文檔展示了如何使用lockzhiner_vision_module::PaddleDet類進行目標檢測,并通過lockzhiner_vision_module::Visualize函數將檢測結果可視
主流的 MCU 開發語言為什么是 C 而不是 C++?
在單片機的地界兒里,C語言穩坐中軍帳,C++想分杯羹?難嘍。咱電子工程師天天跟那針尖大的內存空間較勁,C++那些花里胡哨的玩意兒,在這兒真玩不轉。先說內存這道坎兒。您當stm32f4的256kRAM
C++學到什么程度可以找工作?
C++學到什么程度可以找工作?要使用C++找到工作,特別是作為軟件開發人員或相關職位,通常需要掌握以下幾個方面: 1. **語言基礎**:你需要對C++的核心概念有扎實的理解,包括但不限于指針、內存
發表于 03-13 10:19
C與C++如何互相調用
評論