container_of 宏,它的功能是通过结构中的某个变量获取结构本身的地址,即指针。其定义如下:
#define container_of(ptr, type, member) ({ \
const typeof( ((type *)0)->member ) *__mptr = (ptr); \
(type *)( (char *)__mptr - offsetof(type,member) );})
指针ptr指向type结构成员member,其中offsetof 宏定义如下:
#define offsetof(TYPE, MEMBER) ((size_t) &((TYPE *)0)->MEMBER)
分析可知,__mptr是一个指向type结构里typeof( ((type *)0)->member ) 类型的member成员的指针,offsetof(type,member) 是这个成员在type结构中的偏移,单位是字节。member成员的地址,即__mptr,减去它的偏移便是type结构的起始地址。这跟前面讲的memlist_entry()实现思路同出一辙。
可以预想,通过结构中的某个变量获取结构本身的指针,没有编译器的支持,container_of 宏是难以实现的,至少我是这么认为! |