一、目的
第一次看到linux内核源码遇到这个container_of宏定义的时候难免会有些不知所措,其实这个宏定义的目的就是通过结构体成员的地址获取此结构体的首地址。
二、实战
参考资料
The Magical container_of() Macrohttps://radek.io/2012/11/10/magical-container_of-macro/
#define container_of(ptr, type, member) ({ \
const typeof( ((type *)0)->member ) *__mptr = (ptr); \
(type *)( (char *)__mptr - offsetof(type,member) );})
其中offsetof获取结构体类型type中字段member的偏移地址;typeof获取类型;
当然不严谨的定义可以如下:
#define container_of(ptr, type, member) \
((type *)((char *)(ptr) - (char *)(&((type *)0)->member)))
举例说明
#include <stdio.h>
#define container_of(ptr, type, member) \
((type *)((char *)(ptr) - (char *)(&((type *)0)->member)))
typedef struct {
int x;
int y;
int z;
} foo_t;
int main(int argc, char **argv) {
foo_t a;
foo_t *pa = &a;
int *px = &a.z;
foo_t *pa2 = container_of(px, foo_t, z);
printf("pa: %p, pa2: %p\n", pa, pa2);
return 0;
}
pa: 0x7ffd37026d0c, pa2: 0x7ffd37026d0c
代码中我们使用container_of宏定义通过px的值获取到pa2,然后我们发现pa2与pa的值完全一致。