C/C++开发学习-C++调用写好的C接口
小职 2021-10-19 来源 :编程学习基地 阅读 588 评论 0

摘要:本文主要介绍了C/C++开发学习-C++调用写好的C接口,通过具体的内容展现,希望对大家C/C++的学习有一定的帮助。

本文主要介绍了C/C++开发学习-C++调用写好的C接口,通过具体的内容展现,希望对大家C/C++的学习有一定的帮助。

C/C++开发学习-C++调用写好的C接口

前言

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

 

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

运行无报错

 

思考:那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“这种写法

 

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++调用写好的C接口

本文由 @小职 发布于职坐标。未经许可,禁止转载。
喜欢 | 0 不喜欢 | 0
看完这篇文章有何感觉?已经有0人表态,0%的人喜欢 快给朋友分享吧~
评论(0)
后参与评论

您输入的评论内容中包含违禁敏感词

我知道了

助您圆梦职场 匹配合适岗位
验证码手机号,获得海同独家IT培训资料
选择就业方向:
人工智能物联网
大数据开发/分析
人工智能Python
Java全栈开发
WEB前端+H5

请输入正确的手机号码

请输入正确的验证码

获取验证码

您今天的短信下发次数太多了,明天再试试吧!

提交

我们会在第一时间安排职业规划师联系您!

您也可以联系我们的职业规划师咨询:

小职老师的微信号:z_zhizuobiao
小职老师的微信号:z_zhizuobiao

版权所有 职坐标-一站式IT培训就业服务领导者 沪ICP备13042190号-4
上海海同信息科技有限公司 Copyright ©2015 www.zhizuobiao.com,All Rights Reserved.
 沪公网安备 31011502005948号    

©2015 www.zhizuobiao.com All Rights Reserved

208小时内训课程