加入星计划,您可以享受以下权益:

  • 创作内容快速变现
  • 行业影响力扩散
  • 作品版权保护
  • 300W+ 专业用户
  • 1.5W+ 优质创作者
  • 5000+ 长期合作伙伴
立即加入
  • 正文
  • 推荐器件
  • 相关推荐
  • 电子产业图谱
申请入驻 产业图谱

嵌入式 C 语言知识点,掩码结构体

07/11 12:00
1607
阅读需 6 分钟
加入交流群
扫码加入
获取工程师必备礼包
参与热点资讯讨论

我是老温,一名热爱学习的嵌入式工程师关注我,一起变得更加优秀!

前面的一系列技术文章,我们都曾多次充分说明了,在设计业务逻辑复杂的嵌入式软件时,最好以面向对象作为基本的设计思想,对各个功能模块尽可能地做好封装与解耦。关于嵌入式 C 语言面向对象设计的文章,可以点击以下链接进行回顾:

基于状态机和面向对象的思想,设计一个通用的按键检测模块。

基于面向对象和简单工厂模式,设计一个通用的 LED 显示模块。

嵌入式 C 语言面向对象编程 --- 总结

面向对象是一种基本的设计思想,与所采用的编程语言基本无关(如果非要杠汇编和二进制,那就是你对),一个反面的例子就是,很多人在初学C++的时候,即便C++里面集成了很多面向对象设计的语法糖,但初学者依然会很容易把“类”当作结构体使用。

面向对象的基本出发点是:把“数据属性”与“数据属性的处理方法”都封装在一起。而我们在使用 C 语言进行嵌入式功能模块设计的时候,因为C语言并不具备C++语言的语法糖,所以通常都会使用结构体的方式来模拟类的设计。

因此,我们在使用OOC(Object-Oriented C Programming with ANSI -C)技术的时候,通常都会面临以下问题:

“嗯,我们可以使用结构体来模拟类,把所有数据变量和函数指针都放在结构体里面进行封装,并且把这个结构体放在接口头文件里面,那么问题来了,结构体里面的成员都是public的(语法层面可以直接使用),但某些数据变量却是private属性(不允许被模块外部直接调用)”

那么,应该如何解决这个问题呢?

在我以往编写的 C 语言面向对象文章里面,示例代码的接口头文件,通常都伴随着这个“直接且尖锐”的问题,而通过编码和模块引用规范这一系列的“君子协定”,往往只能起到“防君子而不能防小人”的作用。

直到最近,我看了傻孩子大佬(公众号:裸机思维)的一系列文章才知道,原来C语言里面有一种技法,掩码结构体(Masked Structure),可以为结构体里面的private属性变量盖上一层蒙版,模块使用者即使看到了结构体的私有数据变量,也不能对其进行外部直接访问调用。

在通用的单片机按键检测模块这篇文章里面,对于模块的接口头文件 key_module.h,里面两个最主要的结构体,key_t和key_manager_t,其内部大量暴露了模块的私有参数变量,如下图所示。

模块使用者如果想通过某些简单直接粗暴的方式,去修改模块的各个属性参数,是一件轻而易举(技术上也是合情合理)的事情,因为根据接口头文件的最小信息公开原则,放在头文件的信息内容,难道不是公开且供大家放心使用的么?~

(此刻,作者我,无言以对。。。)

鉴于key_module.h接口头文件显现出来的设计不足,我们可以使用掩码结构体对其进行改进,例如,对于原来的key_t结构体,我们可以把私有不公开的成员,放在struct __key里面,然后 key_t 结构体则改进成如下图所示的方式。

然而,这种改进并未能在真正意义上掩盖住私有成员(struct __key的信息依然表露无遗),因此,我们参考“真刀真枪模块化(2.5)--君子协定”这篇文章,可以通过宏定义技法,把私有成员结构体的信息,真正隐藏起来,如下图所示。

使用以上宏定义,那么我们可以继续对struct __key结构体作出进一步的改进,把结构体的声明和成员定义,都交给了预编译宏进行处理,具体代码如下图所示。

当我们需要提取结构体成员进行使用的时候,可以使用CLASS_INTERNAL宏,该宏展开后是一种强制类型转换,目的是可以通过已知类型的结构体变量,来显式调用结构体成员,使用方式如下图所示。

以上,就是使用掩码结构体技法对单片机按键模块的简单改进(以上截图多数为伪代码,提供一种思路),在实际的工程项目里面,推荐直接使用PLOOC,这个开源项目已经很完美地为C语言面向对象开发提供了必要的OOPC模板。
感谢阅读。

推荐器件

更多器件
器件型号 数量 器件厂商 器件描述 数据手册 ECAD模型 风险等级 参考价格 更多信息
SN74LVC1G17DCKT 1 Texas Instruments Single 1.65-V to 5.5-V buffer with Schmitt-Trigger inputs 5-SC70 -40 to 125

ECAD模型

下载ECAD模型
$0.86 查看
NL17SZ17DFT2G 1 onsemi Single Non-Inverting Buffer with Schmitt Trigger Output, SC-88A (SC-70-5 / SOT-353), 3000-REEL

ECAD模型

下载ECAD模型
$0.19 查看
AST3TQ-T-25.000MHZ-28 1 Abracon Corporation XTAL OSC TCXO 25.0000MHZ LVCMOS
$32.98 查看

相关推荐

电子产业图谱