如何實現(xiàn)在C++中調(diào)用C函數(shù)
如何在C++中調(diào)用C函數(shù)
假如在一個項目中同時包含了C和C++,當C++調(diào)用C函數(shù)時,以傳統(tǒng)C編程#include "xxx.h"后,聲明函數(shù)。
由于main.cpp 是個C++代碼,以C方式的調(diào)用,g++編譯器無法通過編譯。
解決方案一
重寫一個專門被c++用的頭文件(可能存在是別人已經(jīng)寫好的頭文件,我們無法修改等問題)
e.g. 添加一個頭文件 tansfer.h
extern "C" { #include "file1.h" #include "file2.h" }
最后在需要調(diào)用C函數(shù)的cpp文件(即C++文件)中,引用頭文件 tansfer.h即可。
解決方案二
在xxx.h中的每個函數(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文件中實現(xiàn)的函數(shù)
extern "C"的主要作用是為了實現(xiàn)c++代碼能夠調(diào)用c語言代碼。加上extern "C"后,這部分代碼編譯器按c語言的方式進行編譯和鏈接,而不是c++的方式。
原理
由于c++中需要支持函數(shù)重載,所以c和c++中對同一個函數(shù)經(jīng)過編譯后生成的函數(shù)名是不同的,這就會導致一個問題,如果在c++中調(diào)用一個使用c語言編寫模塊中的某個函數(shù),c++是按照c++的名稱修飾方式來查找并鏈接這個函數(shù),就會發(fā)生鏈接錯誤。
- 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++進行鏈接
.c文件和.cpp不能混在一起編譯,要分別編譯成目標文件.o,再進行鏈接生成可執(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ǔ)補充
gcc、g++編譯常用選項:
選項 | 含義 |
-o file | 指定生成的輸出文件名為file |
-E | 只進行預處理 |
-S(大寫) | 只進行預處理和編譯 |
-c(小寫) | 只進行預處理、編譯和匯編 |
C語言分步編譯:
1)預處理:宏定義展開、頭文件展開、條件編譯等,刪除注釋,這里不會檢查語法
gcc -E test.c -o test.i
2)編譯:檢查語法,將預處理后文件編譯成匯編文件
gcc -S test.i -o test.s
3)匯編:將匯編文件生成目標文件(二進制文件)
gcc -c test.s -o test.o
4)鏈接:C語言寫的程序是需要依賴各種庫的,編譯后還需要把庫鏈接到最終的可執(zhí)行程序中去
gcc test.o -o test
總結(jié)
以上為個人經(jīng)驗,希望能給大家一個參考,也希望大家多多支持腳本之家。
相關(guān)文章
C語言數(shù)據(jù)結(jié)構(gòu)之判斷循環(huán)鏈表空與滿
這篇文章主要介紹了C語言數(shù)據(jù)結(jié)構(gòu)之判斷循環(huán)鏈表空與滿的相關(guān)資料,希望通過本文能幫助到大家,讓大家掌握這部分內(nèi)容,需要的朋友可以參考下2017-10-10C++中putchar與getchar函數(shù)的細節(jié)及運用
C語言提供putchar函數(shù),用于給終端輸出一個字符;getchar函數(shù),可以從終端接收用戶輸入的一個字符,本文給大家分享C++中putchar與getchar函數(shù)的細節(jié)及運用,感興趣的朋友跟隨小編一起看看吧2021-07-07C語言 深入解讀數(shù)據(jù)結(jié)構(gòu)之堆的實現(xiàn)
堆就是用數(shù)組實現(xiàn)的二叉樹,所以它沒有使用父指針或者子指針。堆根據(jù)“堆屬性”來排序,“堆屬性”決定了樹中節(jié)點的位置2021-11-11