#ifdef __cplusplus extern "C" { #endif 的细节原理

C语言中的 #ifdef __cplusplus 和 #endif 的作用 C/C++ 语言是一种静态编译语言,编译器在编译代码之前,会先对源代码进行预处理,这些预处理指令是以 # 开头的特殊指令,用来指示编译器完成某些特定的任务。常见的预处理指令包括#define#ifdef#ifndef#include#pragma等。在编译源程序的时候,编译器首先会处理源程序中的预处理指令,将预处理指令替换成相应的代码,最终生成编译后的代码。在编译后的代码中,预处理指令的代码已经被展开或忽略,直接参与编译和链接。 阅读详情
原文转载: 点击打开链接
#ifdef __cplusplus extern "C" { #endif 的解释

1、在好多程序中我们会遇到下面代码段

#ifdef __cplusplus
        extern "C" {
        #endif

//c语法代码段

#ifdef __cplusplus
        }
        #endif //

首先应该知道,__cplusplus是CPP中的自定义宏,则表示这是一段cpp的代码,编译器按c++的方式编译系统.。如果这时候我们需要使用c语言的代码,那么就需要加上(extern "C" { )这一段来说明,要不编译器会把c代码按c++模式编译,会出现问题。

这句话的意思是:这个代码是CPP的代码,__cplusplus是cpp中的自定义宏,因此,以CPP语言的形式编译,但是里面的代码有C语言的代码,那么就要“extern "C" { ”说明一下,编译器用C语言的模式编译。

#ifdef __cplusplus //c++编译环境中才会定义__cplusplus (plus就是"+"的意思)
        extern"C"{ /告诉编译器下面的函数是c语言函数(因为c++和c语言对函数的编译转换不一样,主要是c++中存在重载)
        #endif

要明白为何使用extern "C"{,还得从CPP中对函数的重载处理开始说起。在c++中,为了支持重载机制,在编译生成的汇编码中,要对函数的名字进行一些处理,加入比如函数的返回类型等等。而在C中,只是简单的函数名字而已,不会加入其他的信息。也就是说:C++和C对产生的函数名字的处理是不一样的。 加上extern "C"{ 目的,就是主要实现C与C++的相互调用问题。

extern "C"是连接申明(linkage declaration),被extern "C"修饰的变量和函数是按照C语言方式编译和连接的。

1、C++ 调用C中函数的实例:

c.h的实现

#ifndef _c_h_
        #define _c_h_

        #ifdef __cplusplus
        extern "C" {
                #endif

                void C_fun();

                #ifdef __cplusplus
        }
        #endif

        #endif
        -----------------------------------

c.c的实现

#include "c.h"
        void C_fun()
        {
        }

------------------------------------

在cxx.cpp中调用c.c中的C_fun()

cxx.cpp的实现

#include "c.h"
        int main()
        {
                C_fun()
        }

C++调用C的函数时,在c++的 .h 文件中加extern "C" {}。

所以关键是extern "C" {} ,extern "C"是告诉C++编译器件括号里的东东是按照C的obj文件格式编译的,要连接的话按照C的命名规则去找。

2、C调用C++中的函数CPP_fun()

因为先有C后有C++,所以只能从C++的代码中考虑了。加入C++中的函数或变量有可能被C中的文件掉用,则应该这样写,也是用extern "C"{},不过是代码中要加,头文件也要加,因为可能是C++中也调用

Cxx.h的实现

#ifndef _c_h_
        #define _c_h_

        #ifdef __cplusplus
        extern "C" {
                #endif

                void CPP_fun();

                #ifdef __cplusplus
        }
        #endif

        #endif

Cxx.cpp的实现

extern "C" { //告诉C+++编译器,扩号里按照C的命名规则编译
                void CPP_fun()
                {
                        .....
                }
        }

c.c的实现

#include "Cpp.h"
        int main()
        {
                CPP_fun()
        }

总结:C和C++对函数的处理方式是不同的.extern "C"是使C++能够调用C写作的库文件的一个手段,如果要对编译器提示使用C的方式来处理函数的话,那么就要使用extern "C"来说明。

重要补充:如果C++调用C代码,需要在头文件.h中,添加:

extern "C" {

//C 代码声明;

}

在C代码的实现代码中,有两种方式:

1. 直接修改文件名XXX.c,直接实现,不需要添加extern "C" 声明;

2.如果对于XXX.cpp文件,则需要如下定义:

extern "C" {

//C 代码定义;

}





#ifdef __cplusplus extern "C" { #endif //一段代码 #ifdef __cplusplus } #endif 解读 一般的样式是这样的:#ifdef __cplusplusextern "C"{#endif.......#ifdef __cplusplus}#endif 首先,__cplusplus是cpp中的自定义宏,那么定义了这个宏的话表示这是一段cpp的代码,也就是说,上面的代码的含义是:如果这是一段cpp的代码,那么加入"extern "C"{"  和 " }"处理其中的代码,其中{ }内部的代码是通过... 阅读详情

相关推荐

C/C++编程中extern与extern “C“的深度解析与工程实践

在C/C++多文件编程与混合语言开发中,理解符号的声明、定义与链接过程是解决复杂工程问题的关键基础。编译器在编译阶段处理单个源文件,而链接器则负责将多个目标文件中的符号引用与定义关联起来,生成最终可执行程序。这一机制的核心价值在于实现代码的模块化、复用与跨语言协作,广泛应用于大型项目构建、第三方库集成以及系统级软件开发等场景。其中,extern关键字用于声明外部链接的变量或函数,解决多文件间的全局符号共享问题;而extern "C"链接规范则专门处理C与C++编译器间因名字修饰规则差异导致的符号匹配难题,是

weixin_33811539的博客 304

#ifdef __cplusplus extern “C“{ #endif的作用

https://www.cnblogs.com/HappyXie/archive/2011/01/07/1929369.html

weixin_42031299的博客 7155

C/C++ extern关键字详解:解决未定义引用与跨文件函数调用

在C/C++程序开发中,编译与链接是两个核心构建阶段。编译阶段将每个源文件独立转换为目标文件,而链接阶段则负责将多个目标文件合并为最终可执行程序。这一过程的核心挑战在于符号解析,即确保函数和变量在不同编译单元间的正确引用。extern关键字在此扮演关键角色,它声明函数或变量具有外部链接属性,告知编译器其定义位于其他文件,由链接器最终解析。这一机制是实现代码模块化、支持多文件项目的基础。在C++与C混合编程场景中,由于C++的名称修饰特性,需使用extern "C"指令确保符号兼容性。理解extern的原理与

weixin_30266885的博客 327

#ifdef __cplusplus extern "C" { #endif 的解释

作者:宋老师,华清远见嵌入式学院讲师。 1、在好多程序中我们会遇到下面代码段 #ifdef __cplusplus extern "C" { #endif //c语法代码段 #ifdef __cplusplus } #endif // 首先应该知道,__cplusplus是CPP中的自定义宏,则表示这是一段cpp的代码,编译器按c++的方式编译系统.。如果这时候我们需要使用c

farsightliuht的专栏 1466

嵌入式开发实战:C语言调用C++函数的完整解决方案与原理剖析

在嵌入式系统开发中,C语言因其高效、可预测性成为底层驱动和实时操作系统的首选。然而,随着项目复杂度提升,C++的面向对象特性、模板和标准库在算法和模块封装上展现出显著优势。理解编译链接原理,特别是名字修饰和二进制接口差异,是实现跨语言调用的技术基础。通过extern "C"链接规范和不透明指针技术,可以构建稳定的C兼容接口,使C代码安全调用C++对象。这种混合编程模式在资源受限的嵌入式场景下,既能保持底层效率,又能利用C++的高级特性提升复杂模块的开发质量与可维护性,是平衡性能与工程实践的典型方案。

weixin_34310369的博客 379

杰理AC632N开发板按键配置与GPIO关机保护详解(附CodeBlocks头文件修改避坑)

本文详细解析了杰理AC632N开发板的按键配置与GPIO关机保护实战技巧,包括结构体修改、CodeBlocks头文件缓存问题解决、GPIO保护策略及定时器选择等关键内容。特别提供了充电唤醒实现细节和混合编程注意事项,帮助开发者避开常见陷阱,提升开发效率。

aocan6909的博客 532

关于 #ifdef __cplusplus extern “C“ { #endif

C/C++

holly的专栏 1468

C/C++链接错误multiple definition深度解析:从编译原理到工程实践

在C/C++项目开发中,编译与链接是构建可执行程序的核心环节。编译阶段将源代码转换为目标文件,生成符号表记录定义与引用;链接阶段则负责将多个目标文件拼接,解决符号引用关系。这一过程遵循ODR(One Definition Rule)原则,要求每个全局符号在程序中必须有且仅有一个定义。违反ODR会导致链接器报出multiple definition错误,这是影响项目健壮性的常见问题。理解符号的声明与定义区别、内部链接与外部链接机制,对于构建可维护的大型项目至关重要。本文以典型的DetectClassNameE

weixin_30417487的博客 355

深入解析extern “C“:解决C/C++混合编程链接问题的核心技术

在C/C++混合编程中,链接器报错是常见的技术挑战,其根源在于两种语言对函数名的处理机制不同。C语言采用简单的符号命名规则,而C++引入了名字修饰机制以支持函数重载、命名空间等高级特性,这导致编译后的符号名无法直接匹配。extern "C"作为链接指示符,能够强制C++编译器按照C语言的规则处理函数名,确保跨语言调用的符号一致性。这一技术对于集成第三方C库、实现底层驱动与上层应用的交互具有重要价值,特别是在嵌入式开发、音视频处理等需要高性能底层库的场景中。通过合理使用extern "C",开发者可以高效解决

weixin_30443747的博客 328

ARM嵌入式开发中跨编译器C调用C++库的ABI兼容性解决方案

在嵌入式系统开发中,不同编译器间的ABI(应用程序二进制接口)兼容性是混合编程的核心挑战。ABI定义了函数调用约定、内存布局和名称修饰等底层规范,直接影响二进制代码的互操作性。当使用ARM Compiler 6(如Keil MDK)开发的主程序需要调用Tasking编译器编译的C++静态库时,常因运行时库依赖和名称修饰规则差异导致链接错误。通过创建纯C封装层作为“二进制适配器”,将C++对象的构造/析构和异常处理隔离在单一编译器环境中,可构建稳定的跨编译器接口。这种方法在汽车电子和工业控制等领域具有重要价值

weixin_33843409的博客 467

LabVIEW与C++ DLL混合编程:原理、配置与实战优化指南

动态链接库(DLL)是Windows系统中实现代码复用和模块化的重要技术,它允许程序在运行时加载并调用预编译的函数库,从而提升开发效率和软件性能。其核心原理在于通过导出函数接口和标准调用约定,实现主程序与库之间的二进制交互。在工业自动化与测试测量领域,LabVIEW作为主流的图形化编程平台,常需集成高性能算法或复用现有C/C++代码库,此时通过调用库函数节点(CLFN)与C++ DLL进行混合编程便展现出巨大技术价值。这种架构结合了LabVIEW快速开发UI、处理数据流和硬件I/O的优势,以及C++执行高效

weixin_30699955的博客 389

深入理解extern “C“:解决C++与C语言混合编程的链接问题

在软件开发中,链接(Linking)是将多个编译后的目标文件合并为可执行程序的关键步骤。其核心原理在于解析符号引用,确保函数和变量的声明与定义正确匹配。C++语言支持函数重载等高级特性,编译器会通过名称修饰(Name Mangling)技术生成唯一的内部符号名,而C语言则采用简单的命名规则,这导致两者在二进制接口层面存在不兼容性。这种差异在混合编程场景下尤为突出,例如在嵌入式系统开发或调用遗留C库时,直接链接往往会产生“未定义符号”错误。extern "C"作为一种编译器指令,正是为了解决这一技术难题而设计

weixin_33713350的博客 346

海洋科学—物理海洋学 第五章 海洋环流

本章是基于《海洋科学导论》,但里面涉及到的重要的公式推导是专门拎出来推的,主要借鉴董昌明老师的《物理海洋学导论》,其中有一些多出来的推导,会在更新完整个物理海洋学之后重新拿出来一一讲解,最后开一个番外篇

qq_58518586的博客 1万+

Visual Studio中C/C++混合编程配置与extern “C“使用详解

在软件开发中,混合编程是一种常见的技术实践,它允许不同编程语言编写的模块在同一项目中协同工作。其核心原理在于解决不同编译器间的符号命名与链接规范差异,例如C++的名字修饰与C的简单符号命名规则。这种技术的价值在于能够充分利用现有成熟的C语言生态库,同时结合C++的现代特性进行高效开发。在实际应用场景中,常见于集成历史遗留的C语言库、调用硬件设备的C接口驱动,或在大型项目中实现模块化分工。通过使用extern "C"链接规范,可以明确告知C++编译器对特定代码段采用C语言的链接规则,从而避免链接错误。本文以V

weixin_30600197的博客 512

AOA(Angle of Arrival,到达角)定位算法及其误差分析的原理和MATLAB仿真_aoa定位算法

如图所示,有基站 S 1 ( x 1 , y 1 , z 1 ) , S 2 ( x 2 , y 2 , z 2 ) S_1(x_1,y_1,z_1),S_2(x_2,y_2,z_2) S1​(x1​,y1​,z1​),S2​(x2​,y2​,z2​),目标 T ( x , y , z ) T(x,y,z) T(x,y,z)。2+(z_1-z_2)^2} step1:两基站间的距离L=(x1−x2)2+(y1​−y2​)2+(z1​−z2​)2。

2401_87555613的博客 1482

别再用UE5默认材质:用Substance Painter一招提升写实感

今天,我就把这套从模型准备到引擎最终呈现的全流程技巧毫无保留地分享出来,这套方法不仅能让你的作品细节炸裂,更能让你理解次世代PBR(Physically Based Rendering)材质的底层逻辑。

海外旅居设计师,15年设计经验。 1324

C语言 extern 关键字实战:3个多文件项目案例解析与编译链接原理

本文深入解析C语言extern关键字在多文件项目中的实战应用,通过3个完整案例展示全局变量共享、模块间函数调用和头文件管理的技巧,并详细讲解编译链接原理。掌握extern的正确使用能有效提升C语言模块化开发能力,避免常见编译错误。

weixin_30905133的博客 352

C++ extern关键字详解:跨文件变量共享与C/C++混合编程

在C++编程中,理解变量和函数的声明与定义是构建大型项目的基石。声明告诉编译器符号的类型信息,而定义则分配内存或提供实现。extern关键字的核心作用是强制进行声明并指定外部链接属性,确保符号在不同编译单元间的可见性。这一机制对于实现代码模块化、管理全局变量以及优化编译过程具有重要技术价值。在实际工程中,extern常用于多文件共享全局变量和声明外部函数,特别是在C/C++混合编程场景下,extern "C"能解决因名称修饰规则不同导致的链接问题。本文深入解析extern在跨文件变量共享、链接属性控制以及C

weixin_33701294的博客 364

5.FxBlue跟单常见问题

fxblue喊单ea和fxblue跟单会在mt4/mt5客户端ea栏目里记录fxblue在跟单复制订单过程中的全面记录。在遇到问题时,我们首先要恢复默认参数尝试,然后再到ea栏找报错提示。 ​ 需要注意的是,是EA选项卡,而不是日志选项卡。 此外,您可以在 MT4/5 软件终端面板的"EA"选项卡中查看跟单记录,您可以通过右键单击 Experts 日志并从 MT4/5 的弹出菜单中选择“打开”来打开每日日志文件以及历史文件。 5.1 No “heartbeat” received 没有收到“心跳” 接收方

weixin_44406393的博客 1874

睿尔曼超轻量仿人机械臂--机械臂接口介绍

本文介绍了睿尔曼超轻量仿人机械臂的控制器接口及末端接口。

realman_Rop的博客 3434

C/C++动态链接库开发:从符号导出到跨平台实战

在软件工程中,模块化开发与代码复用是提升开发效率的关键。动态链接库(DLL/SO)作为实现模块化的核心技术,其核心原理在于解决模块间的符号可见性问题——即如何让一个模块的函数或数据被其他模块“看见”并调用。这涉及到编译链接过程中的符号表管理、静态链接与动态链接的区别,以及运行时地址解析等底层机制。从技术价值看,动态链接不仅节省内存、便于更新,更是实现插件化架构、跨语言调用的基础。在应用场景上,无论是开发游戏引擎插件、封装算法库供Python调用,还是构建微服务架构中的共享组件,都离不开动态链接技术。本文聚焦

靓靓软件工作室 504

2023推免(夏令营+套实验室)面试总结(博文附问题汇总和参考答案)

2023推免(夏令营+套实验室)面试总结(博文附问题汇总和参考答案)

m0_51339444的博客 1804

C++设计原理——名称空间(使用、版本管理、别名、重载、嵌套、开放、对类的影响、与C语言的兼容)

C语言缺乏名称空间机制,导致全局名称容易冲突。常见解决方案包括使用宏定义添加前缀(如myprefix_f)或将全局实体封装到类中作为静态成员,但这会破坏封装性、改变初始化顺序并影响链接属性。C语言中可通过static关键字限制函数作用域到单个文件,避免跨文件冲突。C++引入namespace机制,允许将名称限定在特定空间内,通过A::String显式访问,或使用using声明/指令简化调用。相比C语言的解决方案,名称空间更灵活且不影响封装性,是C++管理全局名称的首选方式。

韩江雪de 小屋 373

Palantir 凭什么两年涨 20 倍?深度解析解决 AI 幻觉的 “本体论“ 核心原理

本文深度解析了Palantir本体(Ontology)的核心原理及其在企业AI应用中的革命性价值。本体通过构建结构化的语义层与动态执行层,将企业分散的数字资产(数据集、虚拟表、模型)映射为现实世界的数字孪生,使大模型能够在**严格的业务规则与数据边界内**进行推理与决策,从而从架构层面彻底解决AI幻觉问题。这一技术架构不仅帮助Palantir实现股价两年增长20倍、市值突破4000亿美金的商业成功,更成为SAP、Salesforce等ERP巨头争相模仿的下一代企业智能标准范式。通过航空业飞机故障应急处理等实

program哲学 223

STM32F407中文手册

STM32f407中文手册 本参考手册面向应用开发人员,提供有关使用 STM32F405xx/07xx、STM32F415xx/17xx、 STM32F42xxx 和 STM32F43xxx 微控制器存储器与外设的完整信息。STM32F405xx/07xx、STM32F415xx/17xx、STM32F42xxx 和 STM32F43xxx 构成一个微 控制器系列,各产品具有不同的存储器大小、封装和外设。有关订购信息以及器件的机械与电气特性,请参见数据手册。有关 ARM Cortex™-M4F 内核的信息,请参见《Cortex™-M4F 技术参考手册》。

上一篇: c++ 设计模式1:单件模式
下一篇: 关于VS调试的几个小问题:Edit and Continue(ENC)
Walker Zhang
博客等级 码龄14年 144粉丝 60原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00元
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值