使用 Container_of 在单片机中获取结构体首地址
在单片机的嵌入式开发中,经常需要处理数据结构,比如链表和队列等,而这些数据结构通常是以结构体形式组织的。但有时候需要通过一个成员变量的指针来访问整个结构体,这就需要用到 Container_of 这个宏。
Container_of 是 Linux 内核中的一个宏定义,用来从结构体成员指针得到结构体指针。其使用方法如下:
#define container_of(ptr, type, member) ({
const typeof( ((type *)0)->member ) *__mptr = (ptr);
(type *)( (char *)__mptr - offsetof(type,member) );})
其中,ptr 为结构体成员指针,type 为结构体类型,member 为结构体成员名。
那么,Container_of 的实现原理是什么呢?
Container_of 实现原理
在 C 语言中,结构体是一种复合数据类型。由于结构体成员在内存中是连续存放的,因此每个结构体成员都有一个固定的偏移量。Container_of 利用这个特性来实现从结构体成员指针得到结构体指针的功能。
Container_of 宏定义中的关键是通过 offsetof 宏来获得结构体成员在结构体中的偏移量。offsetof 宏的定义如下:
#define offsetof(TYPE, MEMBER) ((size_t) &((TYPE *)0)->MEMBER)
这个宏用于得到 MEMBER 在 TYPE 结构体中的偏移量。我们把其展开来看:
(TYPE *)0 表示一个空指针类型,由于这是一个指针类型,需要加上 * 才能表示该类型的变量。将其强制转换为结构