Linux内核的container_of宏
作用:
通过一个结构的成员的地址和结构名以及成员名,获得结构的首地址。
宏定义:
include/linux/kernel.h
- /**
- * container_of - cast a member of a structure out to the containing structure
- * @ptr: the pointer to the member.
- * @type: the type of the container struct this is embedded in.
- * @member: the name of the member within the struct.
- *
- */
- #define container_of(ptr, type, member) ({ /
- const typeof( ((type *)0)->member ) *__mptr = (ptr); /
- (type *)( (char *)__mptr - offsetof(type,member) );})
思路很简单:
ptr-(member在type内的偏移地址)
求member在type内的偏移地址有个小技巧,将地址0转换成一个member对象,然后这个对象的成员member的地址就是偏移量。
在宏的定义用用了一个C99的标准宏offsetof,它的作用是取得一个结构体中成员的偏移量。
一个比较常见的宏实现如下:
- /**
- * offset_of - get the offset of a member to its struct
- * @type: the name of the struct
- * @member: the name of the member
- */
- #define offset_of(type,member) ({ /
- (size_t)&(((type*)0)->member);})
在这个宏的最后一句,不能将__mptr转换成void*,因为void*指针不能参与算术运算。
这里是直接用typeof来定义类型。
比如这样:
- const typeof(a) b;
这是一个定义,将b定义成和a一样的类型,且是const的。