如何根据一个结构体成员的地址、结构体类型以及该结构体成员名获得该结构体的首地址?
#define list_entry(ptr, type, member)
((type *)((char *)(ptr)-(unsigned long)(&((type *)0)->member)))
其中,ptr为指向该结构体成员的指针,type为该结构的类型,member为该结构成员的名称。
理解:
&((type *)0)->member的目的是为了获得上图中问号表示的范围的大小。这段代码等价于:
type * p = (type *)0; //便于获得某个结构体成员相对于该结构体起始地址的偏移量
&(p->member); //获得从member结构体成员相对于该结构体首地址的偏移量
还需要注意的是必须将ptr强转为char *类型,这样每次移动一个字节。
(char *)(ptr)-(unsigned long)(&((type *)0)->member) 即为该结构体的首地址,然后将其强转为指向该结构体的指针。