详细介绍:extern “C”关键字

news/2025/10/19 8:22:18/文章来源:https://www.cnblogs.com/ljbguanli/p/19150412

详细介绍:extern “C”关键字

extern “C”

在C++中,**extern“C”**关键字用于指示编译器按照C语言的方式来处理被修饰的代码。这意味着被修饰的函数或变量将不会进行C++的名称修饰(name mangling),从而使得C++代码可以调用C语言的函数或变量。

例如,假设我们有一个C语言的库文件math.c,其中定义了一些数学函数:

// math.c文件
int add (int x,int y)//加法
{return x+y;
}
int sub(int x,int y)//减法
{return x-y;
}
int mult(int x,int y)//乘法
{return x*y;
}
int div(int x,int y) //除法
{return x/y;
}

在C++文件中,我们可以使用**extern“C”来声明这些函数,从而在C++代码中调用它们:

// main.cpp文件
#include 
using namespace std;
extern "C" {int add(int x, int y);int sub(int x, int y);
}
int main() {cout << add(10, 20) << endl; // 输出30cout << sub(10, 20) << endl; // 输出-10return 0;
}

在C++中,extern"C"修饰的语句是按照C语言的方式进行编译的

怎么理解这句话呢?

我来举几个例子:(理解它extern"C"的含义)
我们知道在C++中函数是可以发生重载的,即编译的时候并不会报错,在C语言中,是没有重载的说法的;那么假如我用extern"C"去修饰重载的函数的话,即在编译时候,就会按照C语言的方式去编译了:
这个时候,就会发生错误;
看例子:创建一个main.cpp文件

# include
using namespace std;
extern "C" void func() //用 extern"C"修饰
{
}
extern "C" void func(int v)//用 extern"C"修饰
{
{
}
int main()
{return 0;
}

这时会编译的时候会报错,不允许重载,本来使用C++文件就是可以重载的,但是用extern“C”修饰过后,就不可重载函数了,这就是按照C的编译方式编译,假如按C++编译方式编译那就是能通过的。

extern"C" 也是可以修饰声明函数的,也说明该函数时按照C语言的方式编译;
extern"C" 也是可以用大括号{ } 的方式声明函数的;
如下例子:

extern "C" void func(); //用 extern"C"修饰声明函数
extern "C" void func(int v);//用 extern"C"修饰声明函数
//上诉例子会报错,C语言编译没有重载啊。
///////////////////////////////
///////////////////////////////
///////////////////////////////
extern "C" { //修饰函数声明void func();void func(int v);
} //用大括号的方式一起写进来,也是可以。
//上诉例子会报错,C语言编译没有重载啊。
///////////////////////////////
///////////////////////////////
///////////////////////////////
extern "C" { //修饰函数定义void func(){}void func(int v){}
} //用大括号的方式一起写进来,也是可以。
//上诉例子会报错,C语言编译没有重载啊。
但是可以使用大括号的方式使用extern“C”,这是正确的
# include
using namespace std;
extern "C" void func() //用 extern"C"修饰
{
}void func(int v) //这个不用extern“C”声明{}
int main()
{return 0;
}

上面代码2的情况不会报错,原因很简单:extern "C" void func() { }按C语言方式编译,这个不会错;void func(int v){ }按C++方式编译,所以也不会报错,这两者虽然函数名字相同,但是他们时按照不同的编译方式编译的,所以不报错;

extern"C "使用 在C与C++混合开发中的使用方式
通常在C++ 中,假如需要使用C语言中的库文件的话,可以使用extern "C"去包含;

那如何使用呢?接下来我一步一步带你理解如何使用,先举几个例子。

比如:创建math.c(C文件)中,有一些函数是数学的加法和减法功能函数。
我想在main.cpp文件中使用math.c文件中的函数,如何使用呢?
第一种办法:在main.cpp文件用extern"C"包含math.c文件中的你想用的函数。

//math.c文件
int add (int x,int y)//加法
{return x+y;
}
int sub(int x,int y)//减法
{return x-y;
}
int mult(int x,int y)//乘法
{return x*y;
}
int div(int x,int y) //除法
{return x/y;
}

main.cpp(C++文件)中,要使用math.c文件中的函数.

//main.cpp文件
#include
using namespace std;
extern “C” //用extern“C”{ }声明math.c文件中的函数,以至于可以在main.cpp文件使用。
{int add (int x,int y);int sub(int x,int y);
}
int main()
{cout<

第二种使用方式:

// math.h文件的内容
int add (int x,int y);//加法
int sub(int x,int y);//减法
int mult(int x,int y);//乘法
int div(int x,int y); //除法

假如我有一个需求,我想在main.cpp文件,用math.c文件中的其他函数,比如除法函数,乘法函数;
那么我就只能在 main.cpp 中 extern"C"{ }的括号中,逐个的加上这两个函数;这好像也可以正常使用没问题,但是,这很麻烦啊,别人使用你的.c库时候会先得非常麻烦。所以我们一般使用头文件的方式,即创建多一个头文件math.h,在math.h里声明函数,在math.c文件定义函数,在main.cpp,即要使用该库文件里面,用extern"C"{ } ,在括号里包含该math.h头文件即可

看下math.h头文件内容:

在math.c中定义函数

//math.c文件
int add (int x,int y)//加法
{return x+y;
}
int sub(int x,int y)//减法
{return x-y;
}
int mult(int x,int y)//乘法
{return x*y;
}
int div(int x,int y) //除法
{return x/y;
}

这时候我们只要在main.cpp文件中,用extern “C”{ }包含该头文件就可以使用了。

//main.cpp文件
#include
using namespace std;
extern"C"{ //包含头文件,该里面是C语言方式编译的。# include"math.h"
}
int main()
{cout<

但是,上面的使用方式还是不太好,该方式还是有一定的问题,什么问题呢?就是我在main.cpp文件使用extern "C"{ #include"math.h"} ,即要多写一个 extern"C"{ },显得格外麻烦,再说了,假如还有其他Cpp文件要用这个C语言的库呢。都是这种方式,extern"C"太麻烦啦 。我们之前都是直接#include"math.h",这样才是我们平时的使用习惯呢。

所以有了这第三种使用方式:(为的是直接在main.cpp中,#include"math.h"就可以使用,不用多谢extern"C")

直接在math.h中,用extern"C"的方式修饰就行啦。那么我就可以在main.cpp直接#include"math.h"。

// math.h文件的内容
extern "C" {
int add (int x,int y);//加法
int sub(int x,int y);//减法
int mult(int x,int y);//乘法
int div(int x,int y); //除法
}

上面的使用有并不是完全好的方式,如何说呢?假如我有一个.c文件,创建为other.c,我这个文件呢,也想使用math.c的函数,那么我就可以在other.c文件直接包含该math.c文件就可以了,可是事实却不如所想,这样会报错,报错的原因是,由于在math.h文件中,声明函数用了extern"C",而other.c文件# include"math.h",会包含里面的所有内容,包括里面的 extern"C", 这个extern"C"在other.c文件,即C语言文件是不认识extern"C"啊,所以会报错

下面展示报错的代码,创建other.c文件(C文件),里面包含math.h文件(该文件有extern"C"{ }声明方式 )

//other.c文件
# include"math.h"
//包含头文件,由于这是.c文件,不是.cpp文件。所以.c文件不认识extern"C",所以会报错
void test()
{int ret = add(10,20);//报错,不认识,add.
}

所以如何解决上面问题呢? 核心问题是,我希望有一种使用 extern"C"的方式,在C语言文件中,能够使用该库,在C++文件中也可以使用该库。

要解决这个问题:
也是 第四种使用方式

由于编译器默认会在,你创建的任何一个.cpp文件中,默认定义一个宏 #define __cplusplus,这个宏是你看不到的,是编译器默认给每个.cpp文件创建的,而在.c文件,即C语言的编译器,是没有这个宏的,所以我们可以借助它,来在 math.h文件中使用下面的代码:

看math.h的代码

// math.h文件的内容
//意思是如果使用该头文件math.h的文件定义了__cplusplus,
//则下面代码到#endif都是有效的,在这里是 extern "C" { 有效
#ifdef __cplusplus
extern "C" {
#endif  //__cplusplus
int add (int x,int y);//加法
int sub(int x,int y);//减法
int mult(int x,int y);//乘法
int div(int x,int y); //除法
//意思是如果使用该头文件math.h的文件定义了__cplusplus,
//则下面代码到#endif都是有效的,在这里是 } 有效
#ifdef __cplusplus
}
#endif  //__cplusplus

只要按上面的方式书写,那么就可以完美的解决了在C文件和C++文件中混用的问题;你既可以在.c文件使用该头文件,也可以在.cpp文件中使用该文件库。

第四种方式是最值得推荐的。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/940118.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

PHP 桌面端框架NativePHP for Desktop v2 发布!

PHP 桌面端框架NativePHP for Desktop v2 发布! NativePHP 团队正式发布了 NativePHP for Desktop v2!这是一个重要的主要版本更新,虽然包含一些向后兼容性的破坏性变更,但带来了显著增强的安全默认设置和许多实用的新…

Burp Suite Professional 2025.10 for Windows x64 - 领先的 Web 渗透测试软件

Burp Suite Professional 2025.10 for Windows x64 - 领先的 Web 渗透测试软件Burp Suite Professional 2025.10 for Windows x64 - 领先的 Web 渗透测试软件 世界排名第一的 Web 渗透测试工具包 请访问原文链接:http…

Burp Suite Professional 2025.10 for macOS x64 ARM64 - 领先的 Web 渗透测试软件

Burp Suite Professional 2025.10 for macOS x64 & ARM64 - 领先的 Web 渗透测试软件Burp Suite Professional 2025.10 for macOS x64 & ARM64 - 领先的 Web 渗透测试软件 世界排名第一的 Web 渗透测试工具包 …

[LeetCode] 3397. Maximum Number of Distinct Elements After Operations

You are given an integer array nums and an integer k. You are allowed to perform the following operation on each element of the array at most once: Add an integer in the range [-k, k] to the element. R…

Metasploit Framework 6.4.95 (macOS, Linux, Windows) - 开源渗透测试框架

Metasploit Framework 6.4.95 (macOS, Linux, Windows) - 开源渗透测试框架Metasploit Framework 6.4.95 (macOS, Linux, Windows) - 开源渗透测试框架 Rapid7 Penetration testing, updated Oct 18, 2025 请访问原文链…

Cisco IOS XRv 9000 Router IOS XR Release 7.11.2 MD - 思科 IOS XR 网络操作系统

Cisco IOS XRv 9000 Router IOS XR Release 7.11.2 MD - 思科 IOS XR 网络操作系统Cisco IOS XRv 9000 Router IOS XR Release 7.11.2 MD Cisco IOS XRv 9000 路由器 | 思科 IOS XR 网络操作系统 请访问原文链接:http…

设备端语音处理技术解析

本文详细介绍了设备端语音处理的技术架构,包括自动语音识别模型压缩、量化感知训练、稀疏化方法、分支编码器网络设计,以及硬件软件协同优化方案,实现低延迟和低带宽的语音交互体验。设备端语音处理技术解析 创新训…

毕设项目基于SpringBoot的河南非遗助推平台\251004(白嫖源码+演示录像)可做计算机毕业设计JAVA、PHP、爬虫、APP、小程序、C#、C++、python、资料可视化、文案

pre { white-space: pre !important; word-wrap: normal !important; overflow-x: auto !important; display: block !important; font-family: "Consolas", "Monaco", "Courier New", …

语音技术跨学科研究新趋势

本文探讨了语音技术领域的跨学科融合趋势,包括语音合成与识别模型的循环训练、语言理解改善语音韵律,以及BERT等语言模型在语音系统中的应用,展现了不同技术领域间的协同效应。Interspeech 2022:跨学科研究的增长 …

中国晶圆厂排行榜:谁是下一个台积电

微信视频号:sph0RgSyDYV47z6快手号:4874645212抖音号:dy0so323fq2w小红书号:95619019828B站1:UID:3546863642871878B站2:UID: 3546955410049087半导体是一场长跑——资金、设备、工艺、人才缺一不可。今天我们把…

一首很棒的歌

《冷冷的夏》演唱:王芷蕾作词:姚谦作曲:Bobby Doll 想着他 想他那夜说的话木棉花 怎能灿烂一季夏怪只怪那时不明白话中话 木棉花落尽我才发现我好傻我真的好傻 我好傻 我好傻 迷惑的心四处张望不见炽热的胸膛多情的…

机器学习优化云虚拟机部署技术解析

本文介绍了一种基于决策树机器学习模型的虚拟机部署算法FirePlace,通过历史数据训练模型,在测试中比传统算法提升10%性能,有效解决云环境中虚拟机资源分配和负载均衡问题。使用机器学习优化云环境中的虚拟机部署 在…

251019

251019苹果真是便宜又好吃,但就是觉得没有那些又贵又难吃的水果高贵

每日反思(2025_10_18)

今天刷了几道关于链表的力扣的题

tryhackme-预安全-网络基础知识-什么是网络-04

tryhackme-Pre Security-Pre Security-Network Fundamentals-What is Networking? 房间地址:https://tryhackme.com/room/whatisnetworking 这是网络安全入门的基础模块的计算机科学基础知识:Careers in Cyber(网络…

C++ std::function简单笔记

std::function简单笔记基本形式 #include <iostream> #include <functional>/** * 1. C++11新增的类型别名声明方式 */using pFunc1 = void(); //普通函数 using pFunc2 = void(int, int); //带参…

【C++】基于asio的异步https server

//跨平台异步http server #define _WIN32_WINNT 0x0A00 #include <iostream> #include <vector> #include <string> #include <ctime> //std::tm,std::strftime #include <chrono> #inc…

tryhackme-预安全-网络安全简介-网络职业-03

tryhackme-Pre Security-Introduction to Cyber Security-Careers in Cyber 房间地址:https://tryhackme.com/room/careersincyber 这是网络安全入门的基础模块的计算机科学基础知识:Careers in Cyber(网络职业),…

tryhackme-预安全-网络安全简介-防御性安全简介-02

tryhackme-Pre Security-Introduction to Cyber Security-Defensive Security Intro 房间地址:https://tryhackme.com/room/defensivesecurityintro 这是网络安全入门的基础模块的计算机科学基础知识:Defensive Secu…