1.简介
在Linux上container_of宏使用较为常见,该宏的作用是通过知道结构体中一个成员的地址,从而
计算出,整个结构体的地址,在linux上很多结构体中都包含有struct list_head结构体,通过该list,就可以
得到整个结构体的地址,从而进行操作。
2.解释
在知道container_of之前,首先需要先知道一个offsetof(TYPE, MEMBER)
#define offsetof(TYPE, MEMBER) ((size_t)&((TYPE *)0)->MEMBER)
上述结构是计算出MEMBER在结构体中的偏移量
测试参考:
在知道offsetof宏后,container_of的构成
#define container_of(ptr, type, member) ({ \
const typeof( ((type *)0)->member ) *__mptr = (ptr); \
(type *)( (char *)__mptr - offsetof(type,member) );})
上述为linux4.14上实现,通过member的指针地址-偏移的地址量=计算整个结构体的地址,注意好类型转换,
也就是指针步长(这里转换为char *)。
当然在linux5.0后,该宏进一步演化(增加了)类型判断检查
#define container_of(ptr, type, member) ({ \
void *__mptr = (void *)(ptr); \
BUILD_BUG_ON_MSG(!__same_type(*(ptr), ((type *)0)->member) && \
!__same_type(*(ptr), void), \
"pointer type mismatch in container_of()"); \
((type *)(__mptr - offsetof(type, member))); })
其中BUILD_BUG_ON_MSG,这个在编译的时候,就会对指针类型进行判断。
您还没有登录,请您登录后发表评论。