extern "C"

C++中extern “C”深层探索 C++语言的创建初衷是“a better C”,但是这并不意味着C++中类似C语言的全局变量和函数所采用的编译和连接方式与C语言完全相同。作为一种欲与C兼容的语言,C++保留了一部分过程式语言的特点(被世人称为“不彻底地面向对象”),因而它可以定义不属于任何类的全局变量和函数。但是,C++毕竟是一种面向对象的程序设计语言,为了支持函数的重载,C++对全局函数的处理方式与C有明显的不同。C引用C++函数例子工程中包含的三个文件的源代码如下://C++头文件 cppExample.h#endif。 阅读详情

概述


  extern "C" 包含双重含义,从字面上即可得到:首先,被它修饰的目标是“extern”的;其次,被它修饰的目标是“C”的。让我们来详细解读这两重含义。
(1) 被extern "C"限定的函数或变量是extern类型的
extern是C/C++语言中表明函数和全局变量作用范围(可见性)的关键字,该关键字告诉 编译器 ,其声明的函数和变量可以在本模块或其它模块中使用。记住,下列语句:
extern int a;
仅仅是一个变量的声明,其并不是在定义变量a,并未为a分配内存空间。变量a在所有模块中作为一种全局变量只能被定义一次,否则会出现连接错误。
通 常,在模块的头文件中对本模块提供给其它模块引用的函数和全局变量以关键字extern声明。例如,如果模块B欲引用该模块A中定义的全局变量和函数时只 需包含模块A的头文件即可。这样,模块B中调用模块A中的函数时,在编译阶段,模块B虽然找不到该函数,但是并不会报错;它会在连接阶段中从模块A编译生 成的目标代码中找到此函数。
与extern对应的关键字是static,被它修饰的全局变量和函数只能在本模块中使用。因此,一个函数或变量只可能被本模块使用时,其不可能被extern “C”修饰。
(2) 被extern "C"修饰的变量和函数是按照C语言方式编译和连接的

编译方式


  未加extern “C”声明时的编译方式
首先看看C++中对类似C的函数是怎样编译的。
作为一种 面向对象 的语言,C++支持函数重载,而过程式语言C则不支持。函数被C++编译后在符号库中的名字与C语言的不同。例如,假设某个函数的原型为:
void foo( int x, int y );
该 函数被C编译器编译后在符号库中的名字为_foo,而C++编译器则会产生像_foo_int_int之类的名字(不同的编译器可能生成的名字不同,但是 都采用了相同的机制,生成的新名字称为“mangledname”)。_foo_int_int这样的名字包含了函数名、函数参数数量及类型信息,C++ 就是靠这种机制来实现函数重载的。例如,在C++中,函数void foo( int x, int y )与void foo( int x, float y)编译生成的符号是不相同的,后者为_foo_int_float。
同样地,C++中的变量除支持 局部变量 外,还支持类成员变量和全局变量。用户所编写程序的类成员变量可能与全局变量同名,我们以"."来区分。而本质上,编译器在进行编译时,与函数的处理相似,也为类中的变量取了一个独一无二的名字,这个名字与用户程序中同名的全局变量名字不同。
未加extern "C"声明时的连接方式
假设在C++中,模块A的头文件如下:
// 模块A头文件 moduleA.h
#ifndef MODULE_A_H
#define MODULE_A_H
int foo( int x, int y );
#endif
在模块B中引用该函数:
// 模块B实现文件 moduleB.cpp
#i nclude "moduleA.h"
foo(2,3);
实际上,在连接阶段,连接器会从模块A生成的目标文件moduleA.obj中寻找_foo_int_int这样的符号!
加extern "C"声明后的编译和连接方式
加extern "C"声明后,模块A的头文件变为:
// 模块A头文件 moduleA.h
#ifndef MODULE_A_H
#define MODULE_A_H
extern "C" int foo( int x, int y );
#endif
在模块B的实现文件中仍然调用foo( 2,3 ),其结果是:
(1)模块A编译生成foo的目标代码时,没有对其名字进行特殊处理,采用了C语言的方式;
(2)连接器在为模块B的目标代码寻找foo(2,3)调用时,寻找的是未经修改的符号名_foo。
如果在模块A中函数声明了foo为extern "C"类型,而模块B中包含的是extern int foo( int x, int y ) ,则模块B找不到模块A中的函数;反之亦然。
所 以,可以用一句话概括extern“C”这个声明的真实目的(任何语言中的任何语法特性的诞生都不是随意而为的,来源于真实世界的需求驱动。我们在思考问 题时,不能只停留在这个语言是怎么做的,还要问一问它为什么要这么做,动机是什么,这样我们可以更深入地理解许多问题):
实现C++与C及其它语言的混合编程。
明白了C++中extern "C"的设立动机,我们下面来具体分析extern "C"通常的使用技巧。

习惯用法


  extern "C"的惯用法
(1)在C++中引用C语言中的函数和变量,在包含C语言头文件(假设为cExample.h)时,需进行下列处理:
extern "C"
{
#include "cExample.h"
}
而在C语言的头文件中,对其外部函数只能指定为extern类型,C语言中不支持extern "C"声明,在.c文件中包含了extern "C"时会出现编译语法错误。
笔者编写的C++引用C函数例子工程中包含的三个文件的 源代码 如下:
/* c语言 头文件:cExample.h */
#ifndef C_EXAMPLE_H
#define C_EXAMPLE_H
extern int add(int x,int y);
#endif
/* c语言实现文件:cExample.c */
#i nclude "cExample.h"
int add( int x, int y )
{
return x + y;
}
// c++实现文件,调用add:cppFile.cpp
extern "C"
{
#include "cExample.h"
}
int main(int argc, char* argv[])
{
add(2,3);
return 0;
}
如果C++调用一个C语言编写的.DLL时,当包括.DLL的头文件或声明接口函数时,应加extern "C" { }。
(2)在C中引用C++语言中的函数和变量时,C++的头文件需添加extern "C",但是在C语言中不能直接引用声明了extern "C"的该头文件,应该仅将C文件中将C++中定义的extern "C"函数声明为extern类型。
笔者编写的C引用C++函数例子工程中包含的三个文件的源代码如下:
//C++头文件 cppExample.h
#ifndef CPP_EXAMPLE_H
#define CPP_EXAMPLE_H
extern "C" int add( int x, int y );
#endif
//C++实现文件 cppExample.cpp
#include "cppExample.h"
int add( int x, int y )
{
return x + y;
}
/* C实现文件 cFile.c
/* 这样会编译出错:#include "cExample.cpp" */
extern int add( int x, int y );
int main( int argc, char* argv[] )
{
add( 2, 3 );
return 0;
}
总结   C和C++对函数的处理方式是不同的.extern "C"是使C++能够调用C写作的库文件的一个手段,如果要对编译器提示使用C的方式来处理函数的话,那么就要使用extern "C"来说明。

摘自 http://baike.baidu.com/view/2814224.htm
C++入门>>连接规范---extern “C“ 文章目录前言:背景内部名称修饰extern “C”C++项目调用C静态库C静态库的生成C++项目中C静态库的包含于配置、包含配置一配置二效果C项目调用C++库C++静态库的生成效果总结 前言: 本文介绍C++程序中的连接规范》》extern “C” 博主收集的资料New Young,连载中。 博主收录的问题:New Young 转载请标明出处:New Young 背景 在使用不同编程语言进行软件的开发时,需要统一变量,函数名等的链接规范。 如果C++项目中包含C静态库或者动 阅读详情

相关推荐

extern “C“ 怎么使用? 函数前加 extern 是什么意思? 深度理解 C++ 与 C 代码之间的互操作性

C++ 代码(library.cpp)C 语言代码(main.c)// main.c// 声明 C++ 函数return 0;编译和链接# 编译 C++ 代码 g++ -c library.cpp -o library.o # 编译 C 代码 gcc -c main.c -o main.o # 链接生成可执行文件 g++ main.o library.o -o my_program运行my_program用途extern "C"

Meet_Unknown的博客 1626

【C++】extern “C“ 和 extern 深度探索

本文介绍了C和C++中extern关键字的用法及其在链接阶段的作用。extern用于声明在其他文件中定义的全局变量或函数,实现跨文件共享。extern "C"则是C++特有的用法,用于指示编译器按照C语言的链接规则处理代码,解决C++与C语言的链接兼容性问题,避免名称修饰带来的链接错误。文章还探讨了extern在修饰const变量时的注意事项,以及extern "C"影响本文件符号导出的细节。此外,还讨论了extern "C"对普通类型和C++类型符号导出的影响,以及extern "C"的正确使用方式。

杨翔裕的博客 2123

详解extern “C“的作用

extern "C" 是 C++ 特有的语法,用于在 C++ 代码中声明或定义遵循 C 语言编译和链接规则的函数 / 变量,核心作用是解决 C++ 与 C 语言混合编程时的 “名称修饰(Name Mangling)” 冲突问题。

weixin_41413777的博客 965

C/C++分享点:extern 与extern "C"

C/C++分享点:extern 与extern “C” 1.exern 的作用 1.1 引用同一个文件中的变量 看一段测试代码: #define _CRT_SECURE_NO_WARNING 1 #include<stdio.h> int func(); int main() { func(); printf("%d\n", num); return 0; } in...

lengji22的专栏 814

GWAS与eQTL相结合,进一步筛选疾病相关基因

欢迎关注”生信修炼手册”!在GWAS分析结果中,大部分显著的SNP位点都位于非编码区,很难直接挖掘这些位点的调控机制。通常假设与疾病关联的SNP位点通过调控基因表达来发挥作用,而eQTL...

庐州月光的博客 1万+

URScript介绍

优傲机器人(Universal Robots)是丹麦工业协作机器人制造商,2005年成立,2015年被泰瑞达收购。其自研编程语言URScript基于Python语法,专为机器人控制优化,支持运动指令、IO控制等功能,具有类Python的简洁语法和实时性特点。URScript提供丰富的API,支持变量赋值、条件判断、循环及函数定义等编程结构,参数按值传递。用户可通过该语言在Polyscope界面编写程序,实现自动化任务。目前优傲在全球20多个办事处为多国客户提供服务。

谢谢大家的关注和点赞!这里只有纯纯的知识干货,没有一句废话。希望能实实在在帮到大家~要是觉得有用,别忘了给我点支持哟,你 603

【C++】extern “C“详解

参考: extern “C“的作用及理解 extern C里面能有C++代码吗? 1. 概述 extern “C” 是C++特有的指令(C无法使用该指令),目的在于支持C++与C混合编程。 2. 作用 extern “C” 的作用是告诉C++编译器用C规则编译指定的代码(除函数重载外,extern “C” 不影响C++其他特性)。 3. 原因 为什么要用C规则编译C++代码呢? 因为C和C++的编译规则不一样,主要区别体现在编译期间生成函数符号的规则不一致。 C++比C出道晚,但是增加了很多优秀的功能,.

lemonxiaoxiao的博客 2139

usb gadget uvc driver的code分析

uvc的linux driver分为host侧和gadget侧两个driver。host侧的driver在v4l2框架下,而设备侧的driver在usb/gadget文件夹下。gadget侧的uvc driver,利用v4l2框架去注册video_device,向应用层提供调用接口。同时,它完成v4l2 video buffer拷贝到usb request下的buffer下,然后利用uvc实现的协

lintwins的专栏 1万+

【C++】extern “C“

extern “C” 1. C++调用C 程序不能调用程序,程序只能调用库 (静态库或动态库) 如果想要实现C++去调用C 创建工程,找到静态库 将.c文件的代码写完之后,运行程序,会生成.lib文件 注意:这里是静态库,不需要写main函数,因为不是运行程序 切换到 .cpp文件 一般调用库使用 #include #include "../." . 一个个点号表示当前文件 .. 两个点号表示当前文件的上一个文件 找到 .h文件,其实就是包含一个头文件,就是这个头文件可以不在当前目录或者

Rinne's blog 778

ros2的unity仿真配置(ros2-for-unity)

可以看到unity中输出了Hello World,验证完毕!可以看到unity上监听的/chatter。

m0_63671696的博客 4093

[TI板]MSPM0G3507——keil环境配置+烧录配置+vscode配置+空工程迁移+点灯+芯片解锁教程

本文介绍了MSPM0G3507开发环境的配置与烧录方法。主要内容包括:1)下载安装芯片支持包和SDK开发工具;2)通过串口或DAPLink两种方式实现程序烧录,详细说明了UniFlash软件的使用步骤和常见问题解决方法;3)简要提及工程迁移和LED点灯等基础操作。文章提供了完整的开发环境搭建指南,涵盖从软件安装到实际烧录的全过程,并附有相关工具下载链接和操作截图,帮助开发者快速上手MSPM0G3507开发。

qq_23220445的博客 1万+

extern “C”关键字

操作系统: 进程和线程介绍; 进程:是执行中一段程序,即一旦程序被载入到内存中并准备执行,它就是一个进程。进程是表示资源分配的的基本概念,又是调度运行的基本单位,是系统中的并发执行的单位。 线程:单个进程中执行中每个任务就是一个线程。线程是进程中执行运算的最小单位。 一个线程只能属于一个进程,但是一个进程可以拥有多个线程。多线程处理就是允许一个进程中在同一时刻执行多个任务。 线程是一种轻量级的进程,与进程相比,线程给操作系统带来侧创建、维护、和管理的负担要轻,意味着线程的代价或开销比较小。 线程

qibage的博客 895

14.4kW大功率母线变换器设计:LLC+矩阵变压器+GaN实战解析

在数据中心供电架构中,隔离母线变换器将高压直流母线转换为48V低压母线,是大功率供电链路的核心环节。随着功率密度与效率要求不断攀升,传统移相全桥与普通LLC方案已难以满足300A级输出需求。基于LLC/CLLC谐振拓扑,结合矩阵变压器与GaN功率器件,成为新一代高性能母线变换器的主流技术路线。矩阵变压器将大功率磁性元件拆分为多个小单元,配合原边串联副边并联结构,有效降低绕组损耗并提升功率密度;GaN器件则通过高频软开关进一步压减开关损耗。本文以一台14.4kW样机为例,完整梳理从拓扑选型、谐振参数计算、同步

weixin_28273593的博客 344

关于extern “C“(详细剖析)

目录引言extern “C”的前世今生小心门后的未知世界c++调用c的方法c调用c++的方法 引言 在你工作过的系统里,不知能否看到类似下面的代码。 这好像没有什么问题,你应该还会想:“嗯⋯是啊,我们的代码都是这样写的,从来没有因此碰到过什么麻烦啊~”。 你说的没错,如果你的头文件从来没有被任何C++程序引用过的话。 这与C++有什么关系呢? 看看__cplusplus(注意前面是两个下划线) 的名字你就应该知道它与C++有很大关系。__cplusplus是一个C++规范规定的预定义宏。你可以信任的是:所

Z_Paper的博客 1890

Telegram 担保交易系统搭建指南:安全可靠的交易流程实现

本文介绍了基于Telegram Bot API搭建担保交易系统的完整方案。该系统通过第三方资金托管机制解决买卖双方信任问题,支持"付款后发货"和"收货后放款"的交易流程。文章详细阐述了系统架构设计,包括Telegram Bot交互层、后端业务逻辑层、数据库层和支付接口层。核心实现步骤涵盖:1)订单创建模块处理交易信息;2)支付处理模块集成Stripe Escrow实现资金托管;3)确认收货模块完成资金划转。系统采用PostgreSQL存储交易数据,并通过FastAPI

jingpide9527的博客 1959

华为OD机试真题 C 实现【水库蓄水问题】【2022.11 Q4 新题】

给定一个长度为 n 的整数数组height。数组的元素表示山的高度,选择两个元素作为水库的边界,求蓄水量的最大值并输出蓄水量最大时的边界下标(蓄水量相同时输出下标较近的)。

MISAYAONE的博客 1万+

C++ 中 extern 与 extern “C“ 详解:从跨文件共享到 C/C++ 混合编程

场景 | 说明 || 全局变量跨文件共享 | 一个文件定义,其他文件用extern声明引用 || 全局常量跨文件共享 | 定义时加上,声明时也用| 头文件中的全局变量声明 | 头文件中使用extern声明,在单个 .cpp 中定义 || 跨文件函数调用 | 通常通过头文件声明即可,不需要显式写extern// header.h (错误写法)// 这是定义,不是声明!#include "header.h" // 定义一次。

✨ 欢迎来到【Seal ^_^ 的优快云博客】!✨ 740

计算机控制技术及应用

《计算机控制技术及应用》通过总结作者的科研成果和吸收国内外的先进理论、方法和技术,以计算机控制系统的网络化、开放化、智能化和集成化发展趋势为主线索,主要介绍计算机控制系统的基本概念和计算机控制系统的典型形式,计算机控制系统的数学描述与基本分析方法,以及数字PID控制器、最少拍控制系统、达林算法、状态变量设计法等设计方法及其各种改进算法。重点突出计算机控制系统输入输出通道接口的设计方法和典型控制系统的设计案例与实现方法等。

extern “C“的用法解析

转自:https://www.cnblogs.com/rollenholt/archive/2012/03/20/2409046.html 如涉及作品版权问题,请联系我进行删除。 文章目录1.引言2.从标准头文件说起3.深层揭密extern "C"4.extern "C"的惯用法 1.引言 C++语言的创建初衷是“a better C”,但是这并不意味着C++中类似C语言的全局变量和函数所采用的编译和连接方式与C语言完全相同。作为一种欲与C兼容的语言, C++保留了一部分过程式语言的特点(被世人称为“不彻底

肥宅快乐博客 278

Statistics and Machine Learning Toolbox

Statistics and Machine Learning Toolbox(带书签),MATLAB统计学习工具

Probability and Statistics - 4th edition

Probability and Statistics - 4th edition

C++ extern “C“ 用法

extern “C” 的主要作用就是为了实现 c++ 代码能够调用其他 c 语言代码。

日常解决问题的记录。 672

锂电池充电器电路设计 里面有电路

锂电池充电器电路设计 里面有电路 3.7V升压到5V电路设计。

extern “C“

extern "C"的作用是让C++编译器将修饰的代码按C语言方式编译和链接,避免C++因符号修饰导致与C语言库的链接问题。它常用于调用C语言编写的第三方库接口,如MySQL库。示例展示了如何在C++中使用extern "C"声明C函数sum。此外,通过条件编译#ifdef __cplusplus确保代码在C和C++环境下都能正确编译。

人无远虑,必有近忧 720

extern “C”用法详解

本文主要针对extern "C"的含义进行了解释,并且附带了嵌入式开发中比较常用的一种extern "C"模版,同时也从工程设计的角度对extern关键字的使用进行了解析。

qq_65185318的博客 483

C++中的 extern “C“

是一个链接指示符,用于告诉 C++编译器以 C 语言的方式进行链接。时,要确保 C 函数的声明和定义与 C++程序中的调用方式一致。只影响链接阶段,它并不会改变 C++代码的语法或语义。如果有一个 C 语言库,例如。假设存在一个 C 语言函数。,可以在 C++程序中使用。

凡人叶枫的博客 734

extern “C“作用

123

sy4331的博客 197

Rust 中 extern “C“ 关键字

Rust 中的 extern "C" 关键字

Vallelonga的博客 556

extern "C"与C++中的C函数调用(2)

  前面已经深入了解过extern "C"了,下面进一步探讨一下extern “C”的使用方法。 1、 C代码中包含extern “C”,C代码无法通过编译([1]中C++中调用C的方法1错误)   代码如下: //C代码头文件CDemo.h #include <stdio.h> #ifndef C_SRC_DEMO_H #define C_SRC_DEMO_H ...

weixin_33781606的博客 410

【C/C++ extern“C”的用法,及C++调用C,C调用的C++案例】

而C语言不支持函数重载,也不进行名字修饰,因此直接使用C++编译器编译的C代码(或C++代码中嵌入的C代码)在链接时可能会因为找不到正确的函数名而导致链接错误。在实际项目中,你会在C++代码中通过extern "C"声明C函数,然后在链接时包含C代码编译生成的目标文件(.o或.obj文件)。为了从C代码中调用cpp_function,你需要在C代码中声明这个函数为extern(尽管这不是必须的,因为extern "C"已经在C++代码中声明了),但重要的是确保链接器能找到C++代码编译生成的函数。

一起学习进步! 658
上一篇: 【转帖】#pragma pack(n)
下一篇: 大小端模式的区别(即小尾和大尾的区别)
chennut0802
博客等级 码龄19年 6粉丝 20原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

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

抵扣说明:

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

余额充值