extern “C“的作用以及c/c++代码互调

news2025/1/19 20:19:49

一、目的

相信从事嵌入开发的小伙伴肯定遇到过使用第三库的情景,有时候可能是C++中调用C库,有时候可能又是C中调用C++库;如果你遇到过,那你肯定知道extern "C"的作用.

本篇的目的就是给大家介绍C/C++互相调用的原理和实践。

二、介绍

首先我们需要明确以下几点:

  • c++支持重载,c++中函数编译后名字可能会带上一些参数信息

  • c不支持重载,c中函数编译后在符号表中的名字没有任何改动

假设我们有这样一个头文件print_hello.h

#ifndef PRINT_HELLO_H
#define PRINT_HELLO_H

#ifdef __cplusplus
extern "C" {
#endif

void print_hello(const char *info);

#ifdef __cplusplus
}
#endif
#endif

其中下面代码片段的作用为了避免重复包含导致编译错误

#ifndef PRINT_HELLO_H
#define PRINT_HELLO_H

#endif

下面的代码片段


#ifdef __cplusplus
extern "C" {
#endif

void print_hello(const char *info);

#ifdef __cplusplus
}
#endif

我们将print_hello函数根据当前使用的编译器决定是否包含在extern "C"声明中。

extern "C" {
}

extern/static关键字用于声明变量或者函数的可见性,extern声明的变量或者函数代表除了本模块外其他模块也可见;static声明的变量或者函数只有本模块可见。

我们可以通过extern声明变量或者函数多次,但是只能定义一次。

__cplusplus只有是g++编译器时才会定义。

关键字"C"是指按照C的language linkage进行编译链接。

三、实战

print_hello.c源代码

#include "print_hello.h"

#include <stdio.h>
void print_hello(const char *info) {
    printf("hello %s\n", info);
}
#ifndef PRINT_HELLO_H
#define PRINT_HELLO_H

void print_hello(const char *info);

#endif

编译后查看函数符号

gcc -c print_hello.c -o print_hello.o
readelf -a print_hello.o

从上图我们可以看到gcc编译后的print_hello函数符号名还是print_hello。

下面我们再用g++编译一下看下输出结果

g++ -c print_hello.c -o print_hello.o
readelf -a print_hello.o

从上图我们可以看到g++编译后的print_hello函数符号名变成了_Z11print_helloPKc

下面我们来看一下通过extern "C" 声明编译后的函数名称

#ifndef PRINT_HELLO_H
#define PRINT_HELLO_H

#ifdef __cplusplus
extern "C" {
#endif

void print_hello(const char *info);

#ifdef __cplusplus
}
#endif
#endif
g++ -c print_hello.c -o print_hello.o
readelf -a print_hello.o

再次看一下函数符号信息

从上图我们可以确认的确跟用gcc编译后的效果一样。

那我们再来确认一下通过g++编译后的print_hello函数能不能被c调用

main.c

#include "print_hello.h"

int main() {
    print_hello("world");
    return 0;
}
gcc main.c print_hello.o -o main
readelf -a main

从上图可以确认c的main程序中的确链接上print_hello函数。

以上,就是extern "C"在c/c++互相调用的作用

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

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

相关文章

RK3588平台开发系列讲解(内核调试篇)CPU Hotplug 调试

平台内核版本安卓版本RK3588Linux 5.10Android 12文章目录 一、CPU Hotplug 介绍二、CPU Hotplug 内核开关三、sysfs调试沉淀、分享、成长,让自己和他人都能有所收获!😄 📢多核系统底层驱动提供了cpu的Plugin/Unplug接口,可以实现动态调整cpu使用运行。 一、CPU Hotplu…

在 Node JS 中实现微服务架构

&#x1f4cd;简介&#x1f642; 正如我们在之前的博客“单体与微服务&#xff1a;一种实用方法”中讨论的那样。但是今天我们要在 NodeJS 中实现微服务架构。&#x1f449; 您可以使用任何技术&#xff0c;如 Spring、Python 等。但我们将使用 NodeJS 进行演示。&#x1f4cd;…

PostgreSQL下载、安装和配置使用

1&#xff09;下载 PostgreSQL官网下载&#xff1a;https://www.enterprisedb.com/downloads/postgres-postgresql-downloads 2&#xff09;安装 双击运行安装包 选择安装目录&#xff0c;不推荐安装在C盘。 选择需要安装的服务&#xff0c;不明白是啥的全选就行&#xf…

内含JAVA简单概括和JAVA所需安装的软件和详细教程,想学习JAVA无从下手,这篇文章带你迈出第一步

本文大致概括了JAVA编程语言的简史和特点,主要介绍了JAVA开发环境安装,涉及JDK,Sublime Text IntelliJ IDEA三个软件的简单介绍,安装和使用,最后编写了第一个JAVA代码,保姆级教学,跟着文章一步步来,迈出你学习JAVA的第一步吧! 初识JAVA一.JAVA语言简介二.JAVA发展简史三.JAVA语…

通过模拟器实现APP抓包

本教程将跳过工具安装部分&#xff0c;请正确食用&#x1f609;我的环境&#xff1a;操作系统&#xff1a;win11模拟器版本&#xff1a;雷电安卓模拟器稳定版-安卓7.1(32位) V5.0.46抓包工具&#xff1a;Wireshark-Version 4.0.1抓包工具&#xff1a;charles-Version 4.6.3工具…

SpringMVC(十一):SpringMVC文件上传中要解决的问题

文章目录 SpringMVC文件上传中要解决的问题 一、中文文件名编码问题 二、文件位置存储问题

【YOLO系列】YOLOv8算法(尖端SOTA模型)

前言回顾 在这里粗略回顾一下YOLOv5&#xff0c;这里直接提供YOLOv5的整理的结构图吧 Backbone&#xff1a;CSPDarkNet结构&#xff0c;主要结构思想的体现在C3模块&#xff0c;这里也是梯度分流的主要思想所在的地方&#xff1b;PAN-FPN&#xff1a;双流的FPN&#xff0c;必…

Linux——常用命令1.

✅<1>主页&#xff1a;我的代码爱吃辣 &#x1f4c3;<2>知识讲解&#xff1a;linux &#x1f525;<3>创作者&#xff1a;我的代码爱吃辣 ☂️<4>开发环境&#xff1a;Visual Studio 2022 &#x1f4ac;<5>前言&#xff1a;Linux常用命令 目录 …

Centos7安装JDK1.8(OracleJDK8)

Linux安装JDK1.8 | OracleJDK8Linux安装JDK1.8(OracleJDK8)卸载openJDK官网下载OracleJDK8解压JDK到指定目录配置JDK变量查看jdk是否可用Linux安装JDK1.8(OracleJDK8) Hadoop官方的JDK要求https://cwiki.apache.org/confluence/display/HADOOP/HadoopJavaVersions JDK变量配置…

Java——》下载Hotspot 虚拟机源码

推荐链接&#xff1a; 总结——》【Java】 总结——》【Mysql】 总结——》【Redis】 总结——》【Kafka】 总结——》【Spring】 总结——》【SpringBoot】 总结——》【MyBatis、MyBatis-Plus】 Java——》下载Hotspot 虚拟机源码一、官网下载压…

信息系统基础

目录 一、信息化概述 1.信息的定义 2.信息的特点 3.信息化的概念 4.信息对经济社会的意义 5.信息化对组织的意义 二、信息系统工程的总体规划 1.信息系统工程总体规划方法论 2.信息系统的生命周期和各阶段的目标 三.政府信息化与电子政务 1.电子政务的组成 2.电子政务…

mysql的binlog学习记录

文章目录什么是binlogbinlog格式StatementRowMixedbinlog使用什么是binlog MySQL Binary Log也就是常说的bin-log, ,是mysql执行改动产生的二进制日志文件。简单的来说&#xff0c;binlog日志用于记录所有更新了数据或者以及潜在更新了数据&#xff08;例如&#xff0c;没有匹…

在线学习(online learning)——Chapter 1 What is online learning

在线学习(online learning)——Chapter 1 What is online learning 引用 [1]Hoi S C H, Sahoo D, Lu J, et al. Online learning: A comprehensive survey[J]. Neurocomputing, 2021, 459: 249-289.点击阅读 [2]Orabona F. A modern introduction to online learning[J]. ar…

【1分钟了解网络交换机的6种命令配置模式】

我们在配置交换机的时候首先要了解的就是交换机命令模式&#xff0c;小编用Cisco思科交换机为例带大家了解交换机的6种配置模式。 Cisco IOS提供了用户EXEC模式和特权EXEC模式两种基本的命令执行级别&#xff0c;同时还提供了全局配置、接口配置、Line配置和vlan数据库配置等多…

linux篇【13】:网络应用层—网络版计算器,序列化

目录 一.应用层 1.再谈 "协议" 2.序列化&#xff0c;反序列化 &#xff08;1&#xff09;序列化&#xff0c;反序列化的实例&#xff1a; &#xff08;2&#xff09;自描述长度的协议 3.网络版计算器 细节&#xff08;1&#xff09;&#xff1a;报头方案 &am…

2.13Epd 中景园2.13寸电子墨水屏 显示原理(局部刷新指令)

显示有两种模式&#xff1a; 1、MCU RAM 操作之后一起写入显示屏的RAM 在MCU上分配一个成员大小为8位的数组 长度是像素点数的1/8(一位控制一个像素点) 如图&#xff1a;数组是Image_BW 之后是用 显示的操作算法将每个点由对应的数字或字母 汉字的字模写入数组中 最后将数组一起…

如何尽早发现潜在开发风险,降低项目风险?

1、提前规划风险预防和控制策略 针对开发流程中各环节可能存在的风险&#xff0c;项目经理需进行科学的项目风险分析&#xff0c;提前进行科学地规划和部署&#xff0c;制定符合项目特点的风险评估和监督机制&#xff0c;实行岗位负责制&#xff0c;提前制定控制策略&#xff0…

mac配置MySQL环境

对于开发人员来说&#xff0c;只需要安装MySQL Server 和 MySQL Workbench这两个软件&#xff0c;这样就可以满足开发需求 MySQL Server&#xff1a;专门用来提供数据存储和服务的软件 MySQL Workbench:&#xff1a;可视化的MySQL管理工具&#xff0c;通过他&#xff0c;可以方…

ArcGIS中栅格计算器常用函数的使用

先看下目录 一、 ArcGlS中栅格计算器简介 栅格计算器位置及界面布局 二、 ArcGIS棚格计算器中Con&#xff08;&#xff09;函数的使用 &#xff08;一&#xff09; Con&#xff08;&#xff09;函数的用法 &#xff08;二&#xff09; ArcGIS 案例操作 三、 ArcGIS栅格计算…

Linux 上面安装 RocektMQ 安装

下载 RocketMQ 我下载的版本是&#xff1a;4.9.3 下载地址 Apache Downloads 环境说明 Linux64 位系统JDK1.8 (64位) 安装步骤 第一步&#xff1a;传入文件到 Linux 服务器 先将下载好的包传到 linux 服务器上面去 这里我传入的路径是在 /usr/local 第二步&#xff1a…