C++如何调用已经写好的C接口

 更新时间:2021年10月14日 15:57:51   作者:deroy  
如何在C++代码中调用写好的C接口?你可能会奇怪,C++不是兼容C吗?直接调用不就可以了,那么我们来测试一下,先看看C++如何调用C代码接口的,需要的朋友可以参考一下

前言:

如何在C++代码中调用写好的C接口?你可能会奇怪,C++不是兼容C吗?直接调用不就可以了,那么我们来测试一下,先看看C++如何调用C代码接口的。

1、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.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接口内容请搜索脚本之家以前的文章或继续浏览下面的相关文章希望大家以后多多支持脚本之家!

您可能感兴趣的文章:

相关文章

  • 关于C语言和命令行之间的交互问题

    关于C语言和命令行之间的交互问题

    这篇文章主要介绍了C语言和命令行之间的交互,本文给大家介绍的非常详细,对大家的学习或工作具有一定的参考借鉴价值,需要的朋友可以参考下
    2021-07-07
  • Visual Studio Code运行程序时输出中文成乱码问题及解决方法

    Visual Studio Code运行程序时输出中文成乱码问题及解决方法

    这篇文章主要介绍了解决Visual Studio Code运行程序时输出中文成乱码问题,本文通过图文并茂的形式给大家介绍的非常详细,对大家的学习或工作具有一定的参考借鉴价值,需要的朋友可以参考下
    2020-03-03
  • C++/CLI在vs上的安装和初步使用教程

    C++/CLI在vs上的安装和初步使用教程

    本文给大家介绍C++/CLI在vs上的安装和初步使用,本文通过图文并茂的形式给大家介绍的非常详细,对大家的学习或工作具有一定的参考借鉴价值,需要的朋友参考下吧
    2021-07-07
  • C++实现指针空值的示例代码

    C++实现指针空值的示例代码

    本文主要介绍了C++实现指针空值的示例代码,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧
    2023-06-06
  • 数组中求第K大数的实现方法

    数组中求第K大数的实现方法

    本篇文章是对数组中求第K大数的实现方法进行了详细的分析介绍,需要的朋友参考下
    2013-05-05
  • 使用C语言如何输出逆序数

    使用C语言如何输出逆序数

    逆序数的就是把一个数倒过来,例如:1234那么它的逆序数就为4321,我们该如何是实现呢?下面这篇文章主要给大家介绍了关于使用C语言如何输出逆序数的相关资料,需要的朋友可以参考下
    2022-01-01
  • C语言字符函数中的isalnum()和iscntrl()你都知道吗

    C语言字符函数中的isalnum()和iscntrl()你都知道吗

    这篇文章主要为大家详细介绍了C语言字符函数中的isalnum()和iscntrl(),文中示例代码介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们可以参考一下
    2022-02-02
  • Qt编写地图实现省市区域图的示例代码

    Qt编写地图实现省市区域图的示例代码

    本文主要介绍了Qt编写地图实现省市区域图的示例代码,文中通过示例代码介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们可以参考一下
    2021-12-12
  • C语言函数栈帧的创建和销毁介绍

    C语言函数栈帧的创建和销毁介绍

    大家好,本篇文章主要讲的是C语言函数栈帧的创建和销毁介绍,感兴趣的同学赶快来看一看吧,对你有帮助的话记得收藏一下
    2021-12-12
  • C++中的函数修饰符深入讲解

    C++中的函数修饰符深入讲解

    这篇文章主要给大家介绍了关于C++中函数修饰符的相关资料,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面来一起学习学习吧
    2019-02-02

最新评论