首頁 > 軟體

C++如何呼叫已經寫好的C介面

2021-10-14 19:00:40

前言:

如何在C++程式碼中呼叫寫好的C介面?你可能會奇怪,C++不是相容C嗎?直接呼叫不就可以了,那麼我們來測試一下,先看看C++如何呼叫C程式碼介面的。

1、C++呼叫C檔案

一個C語言檔案test.c

#include <stdio.h> 
void print(int a,int b) 
{ 
    printf("這裡呼叫的是C語言的函數:%d,%dn",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.cppprint(int, int)未定義的參照。

那麼g++編譯器為什麼找不到print(int,int)呢,其實在我們學C++過載的時候就提到過C++底層的編譯原理。

2、原因分析

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語言是 _printC++ __Z5printii

3、解決呼叫失敗問題

修改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 


執行無報錯

4、思考:那C語言能夠呼叫C介面嗎

實驗:定義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「這種寫法

5、C介面既能被C++呼叫又能被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介面的文章就介紹到這了,更多相關C++如何呼叫C介面內容請搜尋it145.com以前的文章或繼續瀏覽下面的相關文章希望大家以後多多支援it145.com!


IT145.com E-mail:sddin#qq.com