您好,登錄后才能下訂單哦!
這篇文章主要介紹了C++怎么調用已經寫好的C接口,具有一定借鑒價值,感興趣的朋友可以參考下,希望大家閱讀完這篇文章之后大有收獲,下面讓小編帶著大家一起了解一下。
一個C語言文件test.c
#include <stdio.h> void print(int a,int b) { printf("這里調用的是C語言的函數:%d,%d\n",a,b); }
一個頭文件test.h
#ifndef _TEST_H #define _TEST_H void print(int a,int b); #endif
C++文件調用C函數
#include <iostream> using namespace std; #include "test.h" int main() { cout<<"現在調用C語言函數\n"; print(3,4); return 0; }
執行命令
gcc -c test.c g++ -o main main.cpp test.o
編譯后鏈接出錯:main.cpp
對print(int, int)
未定義的引用。
那么g++編譯器為什么找不到print(int,int)
呢,其實在我們學C++重載的時候就提到過C++底層的編譯原理。
test.c
我們使用的是C語言的編譯器gcc進行編譯的,其中的函數print
編譯之后,在符號表中的名字為 print
,通過nm查看.o文件.
$ gcc -c test.c $ nm test.o U _GLOBAL_OFFSET_TABLE_ 0000000000000000 T print U printf
我們鏈接的時候采用的是 g++ 進行鏈接,也就是 C++ 鏈接方式,程序在運行到調用 print
函數的代碼時,會在符號表中尋找 _Z5printii
(是按照C++的鏈接方法來尋找的,所以是找 _Z5printii
而不是找 print
)的名字,發現找不到,所以會提示“未定義的引用”
$ 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
此時如果我們在對print
的聲明中加入 extern “C”
,這個時候,g++編譯器就會按照C語言的鏈接方式進行尋找,也就是在符號表中尋找print(這才是C++兼容C),這個時候是可以找到的,是不會報錯的。
總結:
編譯后底層解析的符號不同,C語言是 _print
,C++
是 __Z5printii
修改test.h文件
#ifndef _TEST_H #define _TEST_H extern "C"{ void print(int a,int b); } #endif
修改后再次執行命令
gcc -c test.c g++ -o main main.cpp test.o ./main
運行無報錯
實驗:定義main.c
函數如下
#include <stdio.h> #include "test.h" int main() { printf("現在調用C語言函數\n"); print(3,4); return 0; }
重新執行命令如下
gcc -c test.c gcc -o mian main.c test.o
報錯:C語言里面沒有extern “C“這種寫法
為了使得test.c
代碼既能被C++調用又能被C調用
將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:下期介紹一個Source Insight
的插件,快速生成上面的代碼
再次執行命令
gcc -c test.c gcc -o main main.c test.o ./main
結果示意:
感謝你能夠認真閱讀完這篇文章,希望小編分享的“C++怎么調用已經寫好的C接口”這篇文章對大家有幫助,同時也希望大家多多支持億速云,關注億速云行業資訊頻道,更多相關知識等著你來學習!
免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。