如何實(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ò)編譯。
解決方案一
重寫(xiě)一個(gè)專門(mén)被c++用的頭文件(可能存在是別人已經(jīng)寫(xiě)好的頭文件,我們無(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ǔ)言編寫(xiě)模塊中的某個(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(大寫(xiě)) | 只進(jìn)行預(yù)處理和編譯 |
| -c(小寫(xiě)) | 只進(jìn)行預(yù)處理、編譯和匯編 |
C語(yǔ)言分步編譯:
1)預(yù)處理:宏定義展開(kāi)、頭文件展開(kāi)、條件編譯等,刪除注釋,這里不會(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ǔ)言寫(xiě)的程序是需要依賴各種庫(kù)的,編譯后還需要把庫(kù)鏈接到最終的可執(zhí)行程序中去
gcc test.o -o test
總結(jié)
以上為個(gè)人經(jīng)驗(yàn),希望能給大家一個(gè)參考,也希望大家多多支持腳本之家。
相關(guān)文章
C語(yǔ)言實(shí)現(xiàn)類似wget的進(jìn)度條效果
這篇文章主要介紹了C語(yǔ)言實(shí)現(xiàn)類似wget的進(jìn)度條效果的方法,主要是讓大家可以熟練的使用轉(zhuǎn)移符\r,這里推薦給大家,需要的小伙伴參考下。2015-03-03
OpenCV實(shí)現(xiàn)區(qū)域分割和區(qū)域生長(zhǎng)
區(qū)域分割是圖像處理中一個(gè)重要的任務(wù),本文主要介紹了OpenCV實(shí)現(xiàn)區(qū)域分割和區(qū)域生長(zhǎng),文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧2024-02-02
C++消息隊(duì)列(定義,結(jié)構(gòu),如何創(chuàng)建,發(fā)送與接收)
這篇文章主要介紹了C++消息隊(duì)列(定義,結(jié)構(gòu),如何創(chuàng)建,發(fā)送與接收),消息隊(duì)列是一種先進(jìn)先出的隊(duì)列型數(shù)據(jù)結(jié)構(gòu),實(shí)際上是系統(tǒng)內(nèi)核中的一個(gè)內(nèi)部鏈表2022-08-08
c++11中關(guān)于std::thread的join的詳解
這篇文章主要介紹了c++11中關(guān)于std::thread的join詳解,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧2019-03-03
Qt使用QJson模塊實(shí)現(xiàn)解析Json文件
在項(xiàng)目開(kāi)發(fā)過(guò)程中,經(jīng)常會(huì)遇到讀寫(xiě)Json文件的需求,掌握J(rèn)son文件的操作是基礎(chǔ)中的基礎(chǔ),下面我們就來(lái)看看如何使用QT內(nèi)置的QJson模塊解析Json文件吧2023-10-10

