本文系转载,著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。

作者:宋宝华

来源: 微信公众号linux阅码场(id: linuxdev)

前向声明

编程定律

先强调一点:在一切可能的场景,尽可能地使用前向声明(Forward Declaration)。这符合信息隐蔽的原则。

一个例子

regmap

那么前向声明究竟是个什么鬼?在内核写代码和看代码的童鞋,经常发现Linux内核里面充斥着这样的代码,比如

include/vim linux/regulator/driver.h

文件中:

我们以regmap这个结构体为例,这个地方就是一个前向声明,告诉后面的代码regmap是个结构体,至于这个结构体里面有什么鬼,不知道!

Linux可以说满世界都在使用这个结构体。满世界都在使用声明在include/linux/regmap.h中的regmapwrite()、regmapread()这样的API,可以说无处不在,无处不用,比如drivers/rtc/rtc-at91sam9.c中的:

这样的东西大家随便一搜索,都可以搜索出来无数个。这样看起来,regmap这个结构体,应该是一个跨模块的API,它的整个结构体长成怎么样,应该是出现在一个include/linux/级别的顶级跨模块头文件中了,这样方便跨模块引用这个结构体。

但是,真实的情况却让你大跌眼镜,regmap结构体的具体成员长什么样子,没有出现在任何一个外部级别的头文件里面,而是完全internal的(内部的、内部的、内部的,各位童鞋!!!):

drivers/base/regmap/internal.h

既然它出现在drivers/base/regmap/internal.h,那么想必除了drivers/base/regmap/本身的内部实现外,外部不可能引用drivers/base/regmap/internal.h这个头文件。

所以,我们得出一个结论,尽管Linux满世界都在使用struct regmap,但是除了drivers/base/regmap/内部以外,其实外部没有任何一个人知道regmap这个结构体长成什么样子!!

这是一种极其良好的“高内聚、低耦合”设计。因为,drivers/base/regmap/外部所有的人,其实都只是在拥有regmap这个结构体的指针,而并没有访问regmap结构体其中的任何一个成员,其实也只有drivers/base/regmap/的内部实现在访问而已。

比如,regmap_write实现于:drivers/base/regmap/regmap.c文件,它的代码如下:

这样做带来的一个极大好处是,drivers/base/regmap/外部的世界根本不需要知道regmap结构体长成什么样子,因为没人需要知道,它们都只是在访问regmap的指针!

而drivers/base/regmap/内部无论怎么修改regmap结构体的实现和成员本身,对外部的世界根本不可见,修改regmap结构体后,drivers/base/regmap/以外的模块都不需要重新编译!

相反,如果我们直接把regmap结构体的内部细节暴露在include/linux/regmap.h这个头文件中,那么由于这个头文件满世界都被引用,你只要修改regmap结构体本身,就会导致内核无数模块的增量编译!

include/linux/regmap.h中暴露了regmap_config结构体,这说明这个结构体的内容需要被regmap以外的模块知道:

...

为什么,它涉及到具体的寄存器是如何读写的callback以及具体的寄存器pattern,这肯定是一个API基本的东西,本身就应该是跨模块的东西,所以它的长相出现在了include/linux/regmap.h这个顶级头文件中。

对于一个外部模块而言,它只需要能够通过regmap.h公开暴露的小部分寄存器配置接口,来通过类似regmapinitmmio()这个的API来填充regmap结构体的内部实现。比如drivers/rtc/rtc-at91sam9.c中的:

上述代码中,rtc->gpbr是一个struct regmap指针,regmapinitmmio()在内部填充了regmap的本身实现。之后drivers/rtc/rtc-at91sam9.c再调用regmapwrite()、regmapread()的时候,这些API从regmap模块内部调用我们填充进去的regbits、valbits、reg_stride这些寄存器pattern,帮忙完成寄存器的最终读写。

画一幅图

理清关系

永远用高内聚和低耦合的思想设计代码。Linux内核2000万行的代码,不这么设计肯定要崩盘。写代码不是得过且过。尤其做单片机写裸奔程序的童鞋要特别注意,你们往往觉得玩Linux的童鞋代码一层层套很傻逼,这是完全不正确的理解。

天天要带娃,鸡飞狗跳,没时间写,我随便用碎片时间胡说八道的,不知道各位看官有什么感想?欢迎板砖,也欢迎打赏。

更多精彩更新中……欢迎关注微信公众号:linux阅码场(id: linuxdev)

linux 没有windows.h头文件_宋宝华: Linux内核编程广泛使用的前向声明(Forward Declaration)...相关推荐

  1. Linux内核编程广泛使用的前向声明(Forward Declaration)

    前向声明 编程定律 先强调一点: 在一切可能的场景,尽可能地使用前向声明(Forward Declaration).这符合信息隐蔽的原则. 一个例子 regmap 那么前向声明究竟是个什么鬼? 在内核 ...

  2. c语言windows.h头文件详解

    如果c语言库里没有某个头文件 只需要将下好的头文件放入下面的路径即可 windows.h头文件包含的函数及其用法 1.GetAsyncKeyState()()//通过函数来判断按键按下的状态 主要用法 ...

  3. C语言项目-精忠报国-第二天-COORD windows.h头文件/conio.h getch()函数/game.c showMap()函数 文字突出/怪物计数与打印/随机攻击力 stblib.h

    项目来源:老九君 项目名称:精忠报国之笑傲江湖 视频课地址:网易云课堂 基本功能/架构: 第二天 今天看得比较快,基本把这个项目结束了吧,明天再仔细看一下有没有遗漏的这项目就应该算是结束了.项目难度的 ...

  4. 宋宝华- Linux namespace - Docker 背后的故事

    名称空间是在OS之上实现容器与主机隔离,以及容器之间互相隔离的Linux内核核心技术.根据<Docker 最初的2小时(Docker从入门到入门)>一文,名称空间本质上就是在不同的工作组里 ...

  5. c 如何创建一个.h头文件_微信圈子如何创建,一个全新的“朋友圈”来了?

    在2020年微信公开课PRO不到一个月的时间里,许多微信产品已被重命名和升级.近日,微信正式宣布将微信搜索正式升级为"微信搜索".尽管官方没有进一步的解释,但在微信公开课上透露,微 ...

  6. 宋宝华Linux培训笔记-Linux进程管理

    1.cpu进程状态 linux中进程状态如下图: 浅度睡眠为进程等待资源或中断响应,即使资源没有拿到也可以被唤醒:深度睡眠为进程等待资源,拿到资源后进入就绪状态. 僵死状态为进程死亡,但还没有被父进程 ...

  7. 宋宝华Linux培训笔记-Linux多线程

    1.POSIX标准多线程 发送给进程下一组线程的信号将被共享,被其中任意一个线程处理.同一进程创建的线程同生死,如果收到一个kill信号,这一组task_struce都会退出. 2.NPTL模型 内核 ...

  8. linux pdf 宋宝华,51CTO博客-专业IT技术博客创作平台-技术成就梦想

    原创 宋宝华 Linux阅码场 2018-04-10 前言 网上关于BIO和块设备读写流程的文章何止千万,但是能够让你彻底读懂读明白的文章实在难找,可以说是越读越糊涂! 我曾经跨过山和大海 也穿过人山 ...

  9. 宋宝华: 关于DMA ZONE和dma alloc coherent若干误解的彻底澄清

    原创 宋宝华 Linux阅码场 2018-01-22 作者简介 宋宝华,他有10几年的Linux开发经验.他长期在大型企业担任一线工程师和系统架构师,编写大量的Linux代码,并负责在gerrit上r ...

最新文章

  1. LightOJ1245-Harmonic Number (II) 【数学调和级数】
  2. 常用数据库的 扩展名 格式 后缀 端口
  3. 便利删除_全家便利官方道歉,我们深扒了来龙去脉
  4. opencv学习笔记14:图像礼帽,图像黑帽
  5. ajax,jsonp,axios面试题
  6. javascript 设计模式之单例模式
  7. Sharding-JDBC(操作公共表)_Sharding-Sphere,Sharding-JDBC分布式_分库分表工作笔记013
  8. 速成pytorch学习——4天中阶API示范
  9. 高性能ORM 框架之 MySqlSugar
  10. 图像形态学运算之图像开闭运算 含python实现
  11. Linux端BaiduPCS-Go使用方法
  12. Macs Fan Control Pro for mac(电脑风扇控制软件)v1.5.10中文
  13. 什么是线程安全?如何保证线程安全?
  14. MAC上自定义Office word快捷键
  15. 『NLP经典项目集』10:使用预训练模型优化快递单信息抽取
  16. Linux制作python的AWS-KCL的基础镜像,Dockerfile文件
  17. FastAdmin表单工具栏自定义按钮
  18. 镍氢电池的特性和使用方法(FDK镍氢电池充电机制)
  19. 新海诚没有参与制作的作品_这种新海诚风的摄影作品是怎么制作的?
  20. PHP搭建织梦网站,织梦官方php服务器环境DedeAMPZ安装教程

热门文章

  1. java.util.list e_java.util 类 StackE - Java 中文参考手册
  2. 2012年12月第三个周末
  3. ubuntu安装nginx及其默认目录结构
  4. 洛谷——P1706 全排列问题
  5. ES6学习笔记二 新的声明方式和变量的解构赋值!
  6. 局域网内两台9303 的管理vlan mac地址冲突解决方法
  7. zabbix使用IT services 了解服务器SLA整体情况
  8. zabbix数据库历史数据清除
  9. 细数人们对安卓的误解
  10. CSS 魔法:学海无涯,而吾生有涯