如何實(shí)現(xiàn)在C++中調(diào)用C函數(shù)
如何在C++中調(diào)用C函數(shù)
假如在一個(gè)項(xiàng)目中同時(shí)包含了C和C++,當(dāng)C++調(diào)用C函數(shù)時(shí),以傳統(tǒng)C編程#include "xxx.h"后,聲明函數(shù)。
由于main.cpp 是個(gè)C++代碼,以C方式的調(diào)用,g++編譯器無(wú)法通過(guò)編譯。
解決方案一
重寫一個(gè)專門被c++用的頭文件(可能存在是別人已經(jīng)寫好的頭文件,我們無(wú)法修改等問(wèn)題)
e.g. 添加一個(gè)頭文件 tansfer.h
extern "C" { #include "file1.h" #include "file2.h" }
最后在需要調(diào)用C函數(shù)的cpp文件(即C++文件)中,引用頭文件 tansfer.h即可。
解決方案二
在xxx.h中的每個(gè)函數(shù)最前面添加:extern “C”
extern "C" {? ? ? void fun1(int arg1);? ? ? void fun2(int arg1, int arg2);? ? ? void fun3(int arg1, int arg2, int arg3);? }
解決方案三
在代碼兼容而且少的前提下,更改C文件為cpp文件。
C++程序調(diào)用c函數(shù)(extern “C“的使用)
概念
c++程序調(diào)用c函數(shù),即為在xx.cpp文件中調(diào)用在func.c文件中實(shí)現(xiàn)的函數(shù)
extern "C"的主要作用是為了實(shí)現(xiàn)c++代碼能夠調(diào)用c語(yǔ)言代碼。加上extern "C"后,這部分代碼編譯器按c語(yǔ)言的方式進(jìn)行編譯和鏈接,而不是c++的方式。
原理
由于c++中需要支持函數(shù)重載,所以c和c++中對(duì)同一個(gè)函數(shù)經(jīng)過(guò)編譯后生成的函數(shù)名是不同的,這就會(huì)導(dǎo)致一個(gè)問(wèn)題,如果在c++中調(diào)用一個(gè)使用c語(yǔ)言編寫模塊中的某個(gè)函數(shù),c++是按照c++的名稱修飾方式來(lái)查找并鏈接這個(gè)函數(shù),就會(huì)發(fā)生鏈接錯(cuò)誤。
- c函數(shù):void func(),被編譯成函數(shù):func
- c++函數(shù): void func(){},被編譯成函數(shù):_Z4funcv
示例代碼
1. 處理被調(diào)用的C頭文件
// my_module.h #pragma once #include<stdio.h> #ifdef __cplusplus extern "C"{ #endif void func1(); int func2(int a,int b); #ifdef __cplusplus } #endif // my_module.c #include "my_module.h" void func1() { printf("hello world."); } int func2(int a, int b) { return a+b; } // test.cpp #include "my_module.h" #include<iostream> using namespace std; int main() { func1(); cout << func2(10, 20) << endl; }
編譯:
gcc -c my_module.c -o my_module.o gcc -c test.cpp -o test.o g++ *.o -o test? ?// c++代碼要用g++進(jìn)行鏈接
.c文件和.cpp不能混在一起編譯,要分別編譯成目標(biāo)文件.o,再進(jìn)行鏈接生成可執(zhí)行程序
2. 處理調(diào)用的c++文件
// my_module.h #pragma once #include <stdio.h> void func1(); int func2(int a, int b); // my_module.c #include "my_module.h" void func1() { printf("hello world."); } int func2(int a, int b) { return a+b; } // test.cpp #include <iostream> using namespace std; extern "C" { #include "my_module.h" } int main() { func1(); cout << func2(1, 2) << endl; }
編譯方式同上
基礎(chǔ)補(bǔ)充
gcc、g++編譯常用選項(xiàng):
選項(xiàng) | 含義 |
-o file | 指定生成的輸出文件名為file |
-E | 只進(jìn)行預(yù)處理 |
-S(大寫) | 只進(jìn)行預(yù)處理和編譯 |
-c(小寫) | 只進(jìn)行預(yù)處理、編譯和匯編 |
C語(yǔ)言分步編譯:
1)預(yù)處理:宏定義展開、頭文件展開、條件編譯等,刪除注釋,這里不會(huì)檢查語(yǔ)法
gcc -E test.c -o test.i
2)編譯:檢查語(yǔ)法,將預(yù)處理后文件編譯成匯編文件
gcc -S test.i -o test.s
3)匯編:將匯編文件生成目標(biāo)文件(二進(jìn)制文件)
gcc -c test.s -o test.o
4)鏈接:C語(yǔ)言寫的程序是需要依賴各種庫(kù)的,編譯后還需要把庫(kù)鏈接到最終的可執(zhí)行程序中去
gcc test.o -o test
總結(jié)
以上為個(gè)人經(jīng)驗(yàn),希望能給大家一個(gè)參考,也希望大家多多支持腳本之家。
相關(guān)文章
C語(yǔ)言數(shù)據(jù)結(jié)構(gòu)之判斷循環(huán)鏈表空與滿
這篇文章主要介紹了C語(yǔ)言數(shù)據(jù)結(jié)構(gòu)之判斷循環(huán)鏈表空與滿的相關(guān)資料,希望通過(guò)本文能幫助到大家,讓大家掌握這部分內(nèi)容,需要的朋友可以參考下2017-10-10C++驗(yàn)證LeetCode包圍區(qū)域的DFS方法
這篇文章主要介紹了C++驗(yàn)證LeetCode包圍區(qū)域的DFS方法,本篇文章通過(guò)簡(jiǎn)要的案例,講解了該項(xiàng)技術(shù)的了解與使用,以下就是詳細(xì)內(nèi)容,需要的朋友可以參考下2021-07-07C++中putchar與getchar函數(shù)的細(xì)節(jié)及運(yùn)用
C語(yǔ)言提供putchar函數(shù),用于給終端輸出一個(gè)字符;getchar函數(shù),可以從終端接收用戶輸入的一個(gè)字符,本文給大家分享C++中putchar與getchar函數(shù)的細(xì)節(jié)及運(yùn)用,感興趣的朋友跟隨小編一起看看吧2021-07-07C語(yǔ)言 深入解讀數(shù)據(jù)結(jié)構(gòu)之堆的實(shí)現(xiàn)
堆就是用數(shù)組實(shí)現(xiàn)的二叉樹,所以它沒有使用父指針或者子指針。堆根據(jù)“堆屬性”來(lái)排序,“堆屬性”決定了樹中節(jié)點(diǎn)的位置2021-11-11C++浮點(diǎn)數(shù)在內(nèi)存中的存儲(chǔ)詳解
大家好,本篇文章主要講的是C++浮點(diǎn)數(shù)在內(nèi)存中的存儲(chǔ)詳解,感興趣的同學(xué)趕快來(lái)看一看吧,對(duì)你有幫助的話記得收藏一下2022-01-01