电子产业一站式赋能平台

PCB联盟网

搜索
查看: 198|回复: 0
收起左侧

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

[复制链接]

570

主题

570

帖子

4308

积分

四级会员

Rank: 4

积分
4308
发表于 2024-7-9 17:50:00 | 显示全部楼层 |阅读模式
我是老温,一名热爱学习的嵌入式工程师( @5 E2 ~! p. L3 q  `1 K* F+ ~
关注我,一起变得更加优秀!前面的一系列技术文章,我们都曾多次充分说明了,在设计业务逻辑复杂的嵌入式软件时,最好以面向对象作为基本的设计思想,对各个功能模块尽可能地做好封装与解耦。关于嵌入式 C 语言面向对象设计的文章,可以点击以下链接进行回顾:
& w  C2 i" P# n. a: y  W) Y% F基于状态机和面向对象的思想,设计一个通用的按键检测模块。
* W7 ?  r& J, T+ z+ m基于面向对象和简单工厂模式,设计一个通用的 LED 显示模块。5 A* l- I% J  d& W1 Y4 e
嵌入式 C 语言面向对象编程 --- 总结( T1 y, q# B/ h2 i
面向对象是一种基本的设计思想,与所采用的编程语言基本无关(如果非要杠汇编和二进制,那就是你对),一个反面的例子就是,很多人在初学C++的时候,即便C++里面集成了很多面向对象设计的语法糖,但初学者依然会很容易把“类”当作结构体使用。- [, ^# |: x8 [
面向对象的基本出发点是:把“数据属性”与“数据属性的处理方法”都封装在一起。而我们在使用 C 语言进行嵌入式功能模块设计的时候,因为C语言并不具备C++语言的语法糖,所以通常都会使用结构体的方式来模拟类的设计。
& V+ i- s* @+ c& s! j因此,我们在使用OOC(Object-Oriented C Programming with ANSI -C)技术的时候,通常都会面临以下问题:
& [6 s% Q- K6 K“嗯,我们可以使用结构体来模拟类,把所有数据变量和函数指针都放在结构体里面进行封装,并且把这个结构体放在接口头文件里面,那么问题来了,结构体里面的成员都是public的(语法层面可以直接使用),但某些数据变量却是private属性(不允许被模块外部直接调用)”
  W9 D" q2 |5 G2 {! o9 w  C+ \" c1 Z那么,应该如何解决这个问题呢?
+ y, ~0 v: \9 m: W在我以往编写的 C 语言面向对象文章里面,示例代码的接口头文件,通常都伴随着这个“直接且尖锐”的问题,而通过编码和模块引用规范这一系列的“君子协定”,往往只能起到“防君子而不能防小人”的作用。# d- r, J4 f* G  Q- |% w
直到最近,我看了傻孩子大佬(公众号:裸机思维)的一系列文章才知道,原来C语言里面有一种技法,掩码结构体(Masked Structure),可以为结构体里面的private属性变量盖上一层蒙版,模块使用者即使看到了结构体的私有数据变量,也不能对其进行外部直接访问调用。/ L2 G$ L- D9 \) h0 Y0 s$ s
在通用的单片机按键检测模块这篇文章里面,对于模块的接口头文件 key_module.h,里面两个最主要的结构体,key_t和key_manager_t,其内部大量暴露了模块的私有参数变量,如下图所示。
7 m  p# [+ n/ y( _4 T" \, C# ?

us1lbcgyzlf6402870404.jpg

us1lbcgyzlf6402870404.jpg
) C& L- X5 k( ^+ n) W4 F; V
模块使用者如果想通过某些简单直接粗暴的方式,去修改模块的各个属性参数,是一件轻而易举(技术上也是合情合理)的事情,因为根据接口头文件的最小信息公开原则,放在头文件的信息内容,难道不是公开且供大家放心使用的么?~
, J* }; u! f# g* l(此刻,作者我,无言以对。。。)6 S* z9 R4 G' [/ p' T4 X
鉴于key_module.h接口头文件显现出来的设计不足,我们可以使用掩码结构体对其进行改进,例如,对于原来的key_t结构体,我们可以把私有不公开的成员,放在struct __key里面,然后 key_t 结构体则改进成如下图所示的方式。
/ U/ y( X- N% C* V7 `6 f

ibfukicm0ma6402870505.jpg

ibfukicm0ma6402870505.jpg

" L3 L, u" [9 j然而,这种改进并未能在真正意义上掩盖住私有成员(struct __key的信息依然表露无遗),因此,我们参考“真刀真枪模块化(2.5)--君子协定”这篇文章,可以通过宏定义技法,把私有成员结构体的信息,真正隐藏起来,如下图所示。0 i* o* q8 J9 l) ^8 m! C" N

emesb5witjb6402870605.jpg

emesb5witjb6402870605.jpg

$ r6 d, o2 N: p8 m使用以上宏定义,那么我们可以继续对struct __key结构体作出进一步的改进,把结构体的声明和成员定义,都交给了预编译宏进行处理,具体代码如下图所示。
7 q/ M1 p6 L$ j' F

schoj0jnw456402870705.jpg

schoj0jnw456402870705.jpg
8 j, p9 ~! `# d( E6 w
当我们需要提取结构体成员进行使用的时候,可以使用CLASS_INTERNAL宏,该宏展开后是一种强制类型转换,目的是可以通过已知类型的结构体变量,来显式调用结构体成员,使用方式如下图所示。
. g- ~/ ]  i; @

ecj5bukfajb6402870805.jpg

ecj5bukfajb6402870805.jpg

1 x2 d+ \8 m0 @* c+ m9 z* R以上,就是使用掩码结构体技法对单片机按键模块的简单改进(以上截图多数为伪代码,提供一种思路),在实际的工程项目里面,推荐直接使用PLOOC,这个开源项目已经很完美地为C语言面向对象开发提供了必要的OOPC模板。' \' ~3 p( ~5 r/ |9 L9 v' X- [
感谢阅读。
. ^4 P4 Q8 x" ^  l  {' [-END-- q7 e& F8 U4 m, X% j0 K
往期推荐:点击图片即可跳转阅读4 M  y  x, F. q& A8 k/ o
6 h2 a1 F) D( h/ ^
                                                       
- i: T* P  D3 e, l6 q1 t                                                                ( e, J2 D( P! }" @
                                                                        ' E1 r* B5 b4 \5 A% ]+ }
                                                                                - V7 u3 \$ L! W% A# A

m5pg121aq1h6402870905.jpg

m5pg121aq1h6402870905.jpg
5 o: s; s0 w* {( T
                                                                               
- M2 U6 M6 H2 b5 |) X& F  L                                                                                        嵌入式用 C 语言进行面向对象开发,从未试过如此简单!
4 x" Z; X+ N* ^& X5 Z5 ^% Q. E  c1 t                                                        $ g0 c6 ~/ c  |0 Q8 N/ P( h/ C
                                                               
- Y- t  M# p& O5 r                                                                       
" b: V8 Y, m; {4 W3 O4 F                                                                                $ l& f" s+ E, G2 v: X

5vjnb0epmyu6402871005.jpg

5vjnb0epmyu6402871005.jpg
, x! a' @) B+ j& N- B
                                                                                ! m% O# e' ]8 Z3 D# x3 x+ b
                                                                                        嵌入式 C 语言 struct,面向对象编程的第一步, ?- C9 a5 W2 W) g* V7 {
                                                               
  P! X* [9 i8 f: L3 B. y2 E! V                                                                       
  |. P9 Z$ p; ^; O                                                                               
+ p9 I3 j7 m! h7 o

th5ldry0phn6402871105.jpg

th5ldry0phn6402871105.jpg

* P. Z# @2 u2 a# s                                                                               
; d+ [8 O( q* U                                                                                        面向对象的编程思维5 ^. ?+ T% d5 ~- y; R0 R% U
                                                                               
0 h! Z% d% }) c! n2 q                                                                       
/ j% _! c& s! T                                                               
) ~7 w1 u& K: t; n. g: ^3 _2 i2 V                                                        我是老温,一名热爱学习的嵌入式工程师$ g1 q& S6 ]; }# j2 [
关注我,一起变得更加优秀!
回复

使用道具 举报

发表回复

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则


联系客服 关注微信 下载APP 返回顶部 返回列表