当前位置: 首页 > news >正文

34.extern C的作用

文章目录

  • externC
    • 1.为什么要使用externC
    • 使用externC的一个例子
      • reference


欢迎访问个人网络日志🌹🌹知行空间🌹🌹


externC

1.为什么要使用externC

一句话总结,C++支持函数重载,C语言不支持函数重载,在生成的C++编译文件中函数名会根据参数进行混淆(mangle),而C语言的编译文件不会被混淆,所以在C++程序中链接C语言的函数动态库时需要使用externC来保证函数签名的正确性。

/// main.cppvoid f() {}
void g();extern "C" {void ef() {}void eg();
}/* Prevent g and eg from being optimized away. */
void h() { g(); eg(); }

如上代码,使用命令编译后查看目标文件符号:

g++ -c -std=c++11 -Wall -Wextra -pedantic -o main.o main.cpp
readelf -s main.o
# Symbol table '.symtab' contains 13 entries:
#    Num:    Value          Size Type    Bind   Vis      Ndx Name
#      0: 0000000000000000     0 NOTYPE  LOCAL  DEFAULT  UND 
#      1: 0000000000000000     0 FILE    LOCAL  DEFAULT  ABS test_externC.cc
#      2: 0000000000000000     0 SECTION LOCAL  DEFAULT    1 
#      3: 0000000000000000     0 SECTION LOCAL  DEFAULT    3 
#      4: 0000000000000000     0 SECTION LOCAL  DEFAULT    4 
#      5: 0000000000000000     0 SECTION LOCAL  DEFAULT    6 
#      6: 0000000000000000     0 SECTION LOCAL  DEFAULT    7 
#      7: 0000000000000000     0 SECTION LOCAL  DEFAULT    5 
#      8: 0000000000000000     7 FUNC    GLOBAL DEFAULT    1 _Z1fv
#      9: 0000000000000007     7 FUNC    GLOBAL DEFAULT    1 ef
#     10: 000000000000000e    17 FUNC    GLOBAL DEFAULT    1 _Z1hv
#     11: 0000000000000000     0 NOTYPE  GLOBAL DEFAULT  UND _Z1gv
#     12: 0000000000000000     0 NOTYPE  GLOBAL DEFAULT  UND eg

可以看到被extern "C"修饰的函数ef/gf函数名没有被混淆mangle,而未被函数名包围的按C++的编译规则被混淆了。

使用c++filt _Z1fv命令可以反混淆(unmangle)函数名称,会发现_Z1fv/_Z1hv/_Z1gv对应的就是f/g/h

c++filt是一个用于解码(反编译)低级别的C++Java符号名称的工具,用于将修饰后的函数名映射回源函数名。

使用externC的一个例子

先创建一个C语言的so库:

// add.hint add(int x, int y);// add.c#include <add.h>int add(int x, int y)
{return x + y;
}
/// 编译成so库
/// gcc -fPIC -shared add.c -o libadd.so

通过上面的方式编译的so文件中存在的函数符号名为add,不包含参数名称修饰,因此无法直接被c++程序链接

// main.cc#include <add.h>extern "C" {printf(fmt, ...);
}int main(int argc, char** argv)
{int i = 1, j = 10;printf("%d\n", add(i, j));return 0;
}
/// gcc main.cc -o et -I ./ -L ./ -ladd
/// 报错
/// /usr/bin/ld: /tmp/ccxcRKM6.o: in function `main':
/// main.cc:(.text+0x2f): undefined reference to `add(int, int)'
/// collect2: error: ld returned 1 exit status

要想在c++中使用C语言编译的库,需要在C语言库的头文件中告诉C++哪些代码需要使用C的方式来编译,上面例子将add.h文件改成如下格式即可:

/// add.h
#ifdef __cplusplus
extern "C" {
#endifint add(int x, int y);#ifdef __cplusplus
}
#endif

如此就能正常编译运行了。

reference

1.https://www.geeksforgeeks.org/extern-c-in-c/
2.https://stackoverflow.com/questions/1041866/what-is-the-effect-of-extern-c-in-c

相关文章:

  • 【读博日记】拓扑结构(待修正)
  • Standalone原理讲解与实操演示
  • 考研计算机网络(第一章 概述)
  • 使用 Redis 生成分布式唯一ID
  • python调用SDK的问题
  • 六、Nginx-正向代理和反向代理
  • 吴恩达2022机器学习专项课程C2W3:2.26 机器学习发展历程
  • 最佳websocket封装
  • java8 List的Stream流操作 (实用篇 三)
  • 【Effective Web】常见的css布局方式--三栏布局
  • 网络安全:SQL注入防范
  • 在 React 中使用 ArcGIS JavaScript SDK 构建地图应用
  • STM32高级控制定时器(STM32F103):PWM输出模式
  • 数据赋能(122)——体系:数据清洗——技术方法、主要工具
  • AWS 批量添加安全组
  • python3.6+scrapy+mysql 爬虫实战
  • Android系统模拟器绘制实现概述
  • bearychat的java client
  • Docker 笔记(2):Dockerfile
  • es6(二):字符串的扩展
  • isset在php5.6-和php7.0+的一些差异
  • JavaScript创建对象的四种方式
  • JDK 6和JDK 7中的substring()方法
  • MD5加密原理解析及OC版原理实现
  • MySQL主从复制读写分离及奇怪的问题
  • Netty+SpringBoot+FastDFS+Html5实现聊天App(六)
  • Redash本地开发环境搭建
  • spring security oauth2 password授权模式
  • SpringCloud(第 039 篇)链接Mysql数据库,通过JpaRepository编写数据库访问
  • V4L2视频输入框架概述
  • Vue.js-Day01
  • vue2.0开发聊天程序(四) 完整体验一次Vue开发(下)
  • 高性能JavaScript阅读简记(三)
  • 工作中总结前端开发流程--vue项目
  • 关于List、List?、ListObject的区别
  • 前端临床手札——文件上传
  • 吴恩达Deep Learning课程练习题参考答案——R语言版
  • 因为阿里,他们成了“杭漂”
  • Semaphore
  • ​人工智能书单(数学基础篇)
  • # MySQL server 层和存储引擎层是怎么交互数据的?
  • # Spring Cloud Alibaba Nacos_配置中心与服务发现(四)
  • #数学建模# 线性规划问题的Matlab求解
  • (20)docke容器
  • (4)Elastix图像配准:3D图像
  • (6)添加vue-cookie
  • (9)STL算法之逆转旋转
  • (ibm)Java 语言的 XPath API
  • (ISPRS,2021)具有遥感知识图谱的鲁棒深度对齐网络用于零样本和广义零样本遥感图像场景分类
  • (Redis使用系列) SpirngBoot中关于Redis的值的各种方式的存储与取出 三
  • (层次遍历)104. 二叉树的最大深度
  • (创新)基于VMD-CNN-BiLSTM的电力负荷预测—代码+数据
  • (附源码)springboot电竞专题网站 毕业设计 641314
  • (附源码)计算机毕业设计ssm高校《大学语文》课程作业在线管理系统
  • (论文阅读笔记)Network planning with deep reinforcement learning