C++如何調(diào)用已經(jīng)寫(xiě)好的C接口
前言:
如何在C++代碼中調(diào)用寫(xiě)好的C接口?你可能會(huì)奇怪,C++不是兼容C嗎?直接調(diào)用不就可以了,那么我們來(lái)測(cè)試一下,先看看C++如何調(diào)用C代碼接口的。
1、C++調(diào)用C文件
一個(gè)C語(yǔ)言文件test.c
#include <stdio.h> void print(int a,int b) { printf("這里調(diào)用的是C語(yǔ)言的函數(shù):%d,%d\n",a,b); }
一個(gè)頭文件test.h
#ifndef _TEST_H #define _TEST_H void print(int a,int b); #endif
C++文件調(diào)用C函數(shù)
#include <iostream> using namespace std; #include "test.h" int main() { cout<<"現(xiàn)在調(diào)用C語(yǔ)言函數(shù)\n"; print(3,4); return 0; }
執(zhí)行命令
gcc -c test.c g++ -o main main.cpp test.o
編譯后鏈接出錯(cuò):main.cpp
對(duì)print(int, int)
未定義的引用。
那么g++編譯器為什么找不到print(int,int)
呢,其實(shí)在我們學(xué)C++重載的時(shí)候就提到過(guò)C++底層的編譯原理。
2、原因分析
test.c
我們使用的是C語(yǔ)言的編譯器gcc進(jìn)行編譯的,其中的函數(shù)print
編譯之后,在符號(hào)表中的名字為 print
,通過(guò)nm查看.o文件.
$ gcc -c test.c $ nm test.o U _GLOBAL_OFFSET_TABLE_ 0000000000000000 T print U printf
我們鏈接的時(shí)候采用的是 g++ 進(jìn)行鏈接,也就是 C++ 鏈接方式,程序在運(yùn)行到調(diào)用 print
函數(shù)的代碼時(shí),會(huì)在符號(hào)表中尋找 _Z5printii
(是按照C++的鏈接方法來(lái)尋找的,所以是找 _Z5printii
而不是找 print
)的名字,發(fā)現(xiàn)找不到,所以會(huì)提示“未定義的引用”
$ g++ -c test.c $ ls main.cpp makefile test.c test.h test.o $ nm test.o U _GLOBAL_OFFSET_TABLE_ U printf 0000000000000000 T _Z5printii
此時(shí)如果我們?cè)趯?duì)print
的聲明中加入 extern “C”
,這個(gè)時(shí)候,g++編譯器就會(huì)按照C語(yǔ)言的鏈接方式進(jìn)行尋找,也就是在符號(hào)表中尋找print(這才是C++兼容C),這個(gè)時(shí)候是可以找到的,是不會(huì)報(bào)錯(cuò)的。
總結(jié):
編譯后底層解析的符號(hào)不同,C語(yǔ)言是 _print
,C++
是 __Z5printii
3、解決調(diào)用失敗問(wèn)題
修改test.h文件
#ifndef _TEST_H #define _TEST_H extern "C"{ void print(int a,int b); } #endif
修改后再次執(zhí)行命令
gcc -c test.c g++ -o main main.cpp test.o ./main
運(yùn)行無(wú)報(bào)錯(cuò)
4、思考:那C語(yǔ)言能夠調(diào)用C接口嗎
實(shí)驗(yàn):定義main.c
函數(shù)如下
#include <stdio.h> #include "test.h" int main() { printf("現(xiàn)在調(diào)用C語(yǔ)言函數(shù)\n"); print(3,4); return 0; }
重新執(zhí)行命令如下
gcc -c test.c gcc -o mian main.c test.o
報(bào)錯(cuò):C語(yǔ)言里面沒(méi)有extern “C“這種寫(xiě)法
5、C接口既能被C++調(diào)用又能被C調(diào)用
為了使得test.c
代碼既能被C++調(diào)用又能被C調(diào)用
將test.h修改如下
#ifndef __TEST_H__ #define __TEST_H__ #ifdef __cplusplus #if __cplusplus extern "C"{ #endif #endif /* __cplusplus */ extern void print(int a,int b); #ifdef __cplusplus #if __cplusplus } #endif #endif /* __cplusplus */ #endif /* __TEST_H__ */
ps:下期介紹一個(gè)Source Insight
的插件,快速生成上面的代碼
再次執(zhí)行命令
gcc -c test.c gcc -o main main.c test.o ./main
結(jié)果示意:
到此這篇關(guān)于C++如何調(diào)用已經(jīng)寫(xiě)好的C接口的文章就介紹到這了,更多相關(guān)C++如何調(diào)用C接口內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
關(guān)于C語(yǔ)言和命令行之間的交互問(wèn)題
這篇文章主要介紹了C語(yǔ)言和命令行之間的交互,本文給大家介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下2021-07-07Visual Studio Code運(yùn)行程序時(shí)輸出中文成亂碼問(wèn)題及解決方法
這篇文章主要介紹了解決Visual Studio Code運(yùn)行程序時(shí)輸出中文成亂碼問(wèn)題,本文通過(guò)圖文并茂的形式給大家介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下2020-03-03數(shù)組中求第K大數(shù)的實(shí)現(xiàn)方法
本篇文章是對(duì)數(shù)組中求第K大數(shù)的實(shí)現(xiàn)方法進(jìn)行了詳細(xì)的分析介紹,需要的朋友參考下2013-05-05C語(yǔ)言字符函數(shù)中的isalnum()和iscntrl()你都知道嗎
這篇文章主要為大家詳細(xì)介紹了C語(yǔ)言字符函數(shù)中的isalnum()和iscntrl(),文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2022-02-02Qt編寫(xiě)地圖實(shí)現(xiàn)省市區(qū)域圖的示例代碼
本文主要介紹了Qt編寫(xiě)地圖實(shí)現(xiàn)省市區(qū)域圖的示例代碼,文中通過(guò)示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2021-12-12C語(yǔ)言函數(shù)棧幀的創(chuàng)建和銷(xiāo)毀介紹
大家好,本篇文章主要講的是C語(yǔ)言函數(shù)棧幀的創(chuàng)建和銷(xiāo)毀介紹,感興趣的同學(xué)趕快來(lái)看一看吧,對(duì)你有幫助的話(huà)記得收藏一下2021-12-12