栏目分类:
子分类:
返回
名师互学网用户登录
快速导航关闭
当前搜索
当前分类
子分类
实用工具
热门搜索
名师互学网 > IT > 软件开发 > 后端开发 > C/C++/C#

158-C++基础(C和C++的相互调用)

C/C++/C# 更新时间: 发布时间: IT归档 最新发布 模块sitemap 名妆网 法律咨询 聚返吧 英语巴士网 伯小乐 网商动力

158-C++基础(C和C++的相互调用)

C和C++的相互调用?

C 调用 C++:无法直接调用了!怎么办?

  • 把C++源码扩在extern “C”

C++ 调用 C代码:无法直接调用了!怎么办?

  • 把C函数的声明扩在extern "C"里面
1、C++ 调用 C代码(把C函数的声明扩在extern "C"里面)

我们写一个.c文件:

我们在另一个.cpp文件进行调用这个sum函数:
直接声明即可,和包含c文件的头文件是一样的;

编译看看:

  • 链接错误,因为编译器按照C++的标准生成符号(函数名+参数列表),在链接的时候发现这里有一个未定义的符号,就在其他的.obj或者.o文件都找,但是找不到。

  • 在编译的时候,c文件总的sum函数在.text段
  • C++中生成sum函数的符号时:

    因为是符号的引用,所以是UND类型
  • 在链接的时候,链接器发现cpp的.o文件中sum_int_int(简写的)是一个未定义的符号,链接器会在其他的.o文件中找 sum_int_int符号,找不到!!!
  • 因为在C文件中,编译器是按照C语言的规则去生成符号的,自然匹配不到C++文件中的函数符号。

这样就导致了,C++调用C代码,无法直接调用。

  • 把C函数的声明扩在extern "C"里面

  • 告诉编译器,这个函数是在C语言规则下生成的,所以你在生成符号的时候,不要按照C++的方式,要按照C语言的规则去生成符号。

  • C++编译器看到就会知道这是一个C的API接口,就会按照C的API接口来生成sum函数的符号,链接的时候就会在c函数的.o文件中找到符号定义的地方。 (符号解析完成后,就会给符号分配虚拟地址进行符号重定向)

2、C 调用 C++函数(把C++源码扩在extern “C”)

此时sum函数是在C++中定义的:

在.c文件中调用:

运行结果:

直接报错!

原因:

c函数中的sum符号和c++中的sum符号是不一样的!!!

解决方法:

  • 在C++文件中的sum函数实现外部扩上extern C
  • 在C++文件中告诉编译器,按照C语言的方式生成这个函数的符号;这样在C文件调用这个函数,就可以找到了。

注意:extern “”是只有C++编译器才认识的C编译器不认识extern""

面试问题:__cplusplus宏
  • __FILE__:这个是直接打印当前代码的文件名称
  • __LINE__:这个是直接打印当前代码的行数
  • 上面2个是属于编译器内置的宏
//__FILE__//这个是直接打印当前代码的文件名称 
//__LINE__//这个是直接打印当前代码的行数 
//上面2个是属于编译器内置的宏 

//只要是C++编译器,都内置了__cplusplus这个宏名
#ifdef __cplusplus//这个宏 
extern "C" {
#endif
	int sum(int a, int b) // sum  .text
	{
		return a + b;
	}
#ifdef __cplusplus
}
#endif
//这样的书写是,如果有定义 __cplusplus这个宏(C++编译器内置的宏),就执行下面的extern C,按照C规则生成函数符号
//如果是用C编译器编译这段代码的话,就没有定义 __cplusplus这个宏,所以就不进去下面的extern C, sum函数也是生成C规则的符号 

这样书写的结果就是:

  • 不管是C编译器生成还是C++编译器生成,都是按照C规则去生成函数符号的!都是可以直接给其他的C项目调用的!
转载请注明:文章转载自 www.mshxw.com
本文地址:https://www.mshxw.com/it/862168.html
我们一直用心在做
关于我们 文章归档 网站地图 联系我们

版权所有 (c)2021-2022 MSHXW.COM

ICP备案号:晋ICP备2021003244-6号