C/C++混合编程之extern “C”的使用示例

发布时间 - 2026-01-11 03:14:23    点击率:

前言

本文主要给大家介绍了关于C/C++混合编程extern “C”使用的相关内容,分享出来供大家参考学习,下面话不多说了,来一起看看详细的介绍吧。

首先要明白:

C++号称是C语言的超集,也确实,从语言的基本语法上,C++是包含所有C语言的语法的,而且C++为了兼容C,连C语言的标准库也被纳入到C++的标准库中,比如在C++中我们仍然可以使用<stdio.h> ,它就是C++标准库的一部分(注意最好用新的标准<cstdio> ,而不是老的<stdio> )。

但是,C++和C语言的编译器在有些地方还是有差别的。比如,C++是支持面向对象的特性(尽管C++被称为不彻底的面向对象语言),面向对象就要支持函数重载,而函数重载的实现和C++编译器是分不开的。

比如有:

int max(int a, int b);

double max(double a,double b);

这两个函数。

这两个函数同时存在,在C语言中是不可以的,因为C语言不支持重载,但是在C++中完全没有问题,因为C++是支持重载的。

那么为什么会这样呢?

这要从编译器的角度来看:

C编译器将int max(int a,int b)函数编译后,在符号库中的名字为_max(不同编译器可能有不同的形式)

C编译器将double max(double a,double b)函数编译后,在符号库中的名字也为_max。所以在C语言中,这两个函数是不能共存的的,编译时会提示错误。

但是C++编译器则不同

C++编译器将int max(int a, int b)编译后,在符号表中的名字为:

_max_int_int

而另一个则为_max_double_double。这两者并不冲突。

这也是C++支持函数重载的根本原因。不过,这也从另一面说明了:函数重载其实不是多态,顶多算是编译时多态。

在C++和C混合编程时:

在C++和C语言混合编程时,前面已经说过,C++的语法是完全包含C语言的语法的,所以不用担心语法上出现什么问题。出现问题的主要原因在编译和链接时。

思考这样一件事情:

我们在Linux下编程的时候,经常会用到内核的库,我们知道Linux内核使用C语言写的。如果这些库采用了C语言的编译器进行编译,而我们的程序是用C++开发的,要用C++进行编译,那么会出现什么问题?

比如:

我们有个.c文件p.c,内容如下:

#include <stdio.h>

void print(int a,int b)
{
  printf("这里调用的是C语言的函数:%d,%d\n",a,b);
}

我们用gcc –c命令编译它,生成p.o文件

然后我们又p.h文件,里面是print函数的原型声明,如下:

void print(int a,int b);

我们又有main.cpp文件,内容如下

#include <iostream>

using namespace std;

#include "p.h"

int main()
{
  cout<<"现在调用C语言函数\n";
  print(3,4);
  return 0;

}

这次我们用g++ -c进行编译,生成main.o文件

然后我们用g++链接两个.o文件,这时我们会发现,报错:

 

这时为什么呢?

因为:

p.c我们使用的是C语言的编译器gcc进行编译的,其中的函数print编译之后,在符号表中的名字为 _print

而我们链接的时候采用的是g++进行链接,也就是C++链接方式,程序在运行到调用print函数的代码时,会在符号表中寻找_print_int_int(是按照C++的链接方法来寻找的,所以是找_print_int_int而不是找_print)的名字,发现找不到,所以会t提示“未定义的引用”

此时如果我们在对print的声明中加入 extern “C” ,这个时候,g++编译器就会按照C语言的链接方式进行寻找,也就是在符号表中寻找_print,这个时候是可以找到的,是不会报错的。比如我们修改p.h为:

extern "C" void print(int a,int b);

这是结果为:

 

所以extern “C” 用到函数声明之前,它的作用就是告诉编译器,对于该函数的链接要采用C语言编译器的链接方式,也就是告诉编译器找_fun,而不是_fun_int_int。

如果有多个函数声明都需要在前面加extern “C”,那可以用extern “C”{}的形式。

总结

以上就是这篇文章的全部内容了,希望本文的内容对大家的学习或者工作具有一定的参考学习价值,如果有疑问大家可以留言交流,谢谢大家对的支持。


# c  # extern用法  # c语言  # extern  # c语言extern用法  # C/C++开发中extern的一些使用注意事项  # C/C++中extern函数使用详解  # C/C++ extern和static的使用详解  # C/C++ 中extern关键字详解  # C/C++ extern关键字用法示例全面解析  # 的是  # 这两个  # 面向对象  # 库中  # 而不是  # 这个时候  # 报错  # 什么问题  # 这是  # 就会  # 是在  # 多态  # 有个  # 相关内容  # 是有  # 也就  # 多个  # 说了  # 如有  # 找不到 


相关栏目: 【 网站优化151355 】 【 网络推广146373 】 【 网络技术251813 】 【 AI营销90571


相关推荐: 谷歌Google入口永久地址_Google搜索引擎官网首页永久入口  Laravel如何集成第三方登录_Laravel Socialite实现微信QQ微博登录  微信公众帐号开发教程之图文消息全攻略  佛山企业网站制作公司有哪些,沟通100网上服务官网?  Android中AutoCompleteTextView自动提示  Laravel如何实现URL美化Slug功能_Laravel使用eloquent-sluggable生成别名【方法】  Laravel如何创建自定义Facades?(详细步骤)  如何在新浪SAE免费搭建个人博客?  如何在企业微信快速生成手机电脑官网?  制作ppt免费网站有哪些,有哪些比较好的ppt模板下载网站?  Bootstrap CSS布局之列表  如何在宝塔面板中创建新站点?  php静态变量怎么调试_php静态变量作用域调试技巧【解答】  如何在橙子建站上传落地页?操作指南详解  Laravel如何构建RESTful API_Laravel标准化API接口开发指南  在线教育网站制作平台,山西立德教育官网?  Laravel如何使用API Resources格式化JSON响应_Laravel数据资源封装与格式化输出  在线制作视频的网站有哪些,电脑如何制作视频短片?  通义万相免费版怎么用_通义万相免费版使用方法详细指南【教程】  Win11怎么关闭专注助手 Win11关闭免打扰模式设置【操作】  Windows驱动无法加载错误解决方法_驱动签名验证失败处理步骤  家族网站制作贴纸教程视频,用豆子做粘帖画怎么制作?  HTML5打空格有哪些误区_新手常犯的空格使用错误【技巧】  Laravel Eloquent关联是什么_Laravel模型一对一与一对多关系精讲  Laravel如何使用Service Container和依赖注入?(代码示例)  微信小程序 闭包写法详细介绍  MySQL查询结果复制到新表的方法(更新、插入)  Android滚轮选择时间控件使用详解  黑客如何通过漏洞一步步攻陷网站服务器?  Laravel如何处理JSON字段的查询和更新_Laravel JSON列操作与查询技巧  邀请函制作网站有哪些,有没有做年会邀请函的网站啊?在线制作,模板很多的那种?  iOS UIView常见属性方法小结  太平洋网站制作公司,网络用语太平洋是什么意思?  广州网站制作公司哪家好一点,广州欧莱雅百库网络科技有限公司官网?  网站制作企业,网站的banner和导航栏是指什么?  如何在IIS中配置站点IP、端口及主机头?  Win11搜索栏无法输入_解决Win11开始菜单搜索没反应问题【技巧】  如何在Windows环境下新建FTP站点并设置权限?  Win11应用商店下载慢怎么办 Win11更改DNS提速下载【修复】  手机钓鱼网站怎么制作视频,怎样拦截钓鱼网站。怎么办?  Laravel怎么进行数据库回滚_Laravel Migration数据库版本控制与回滚操作  Laravel如何获取当前用户信息_Laravel Auth门面获取用户ID  标准网站视频模板制作软件,现在有哪个网站的视频编辑素材最齐全的,背景音乐、音效等?  如何快速搭建高效香港服务器网站?  Laravel项目如何进行性能优化_Laravel应用性能分析与优化技巧大全  Laravel Vite是做什么的_Laravel前端资源打包工具Vite配置与使用  如何在 Python 中将列表项按字母顺序编号(a.、b.、c. …)  千库网官网入口推荐 千库网设计创意平台入口  Windows10电脑怎么设置虚拟光驱_Win10右键装载ISO镜像文件  实例解析Array和String方法