Linux 内核 --offsetof 和 container_of
1 |
|
offsetof
:获取结构体中成员的偏移位置,将地址 0
强制转换为 type
类型的指针(编译器认为 0
是一个有效地址,即 0
是type
指针的起始地址),然后再引用 member
成员(对应的就是 ((type *)0)->member
,即偏移到member
成员的起始地址),最后将 member
成员的起始地址强制转换为 size_t
类型
1
2
3
4
struct Test {
char text[32];
int count;
}If
struct Test
is allocated at the address0xC000
, then the address oftext
would be0xC000
, and the address ofcount
would be0xC020
. However, if the base address is zero (which is not allowed by the standard), then the address oftext
would be zero, and the address of the count would be0x20
. Casting these addresses tosize_t
gives you the offset of the corresponding members.
1 |
|
container_of
:const typeof(((type *)0)->member ) *__mptr = (ptr);
通过 typeof
定义一个 member
指针类型的指针变量 __mptr
(即__mptr
是指向 member
类型的指针),并将 __mptr
赋值为 ptr
;(type *)((char *)__mptr - offsetof(type,member));
通过 offsetof
宏计算出 member
在type
中的偏移,然后用 member
的实际地址 __mptr
减去偏移,得到 type
的起始地址,即指向 type
类型的指针