#define list_entry(ptr, type, member) \
((type *)((char *)(ptr)-(unsigned long)(&((type *)0)->member)))
这个倒是不难理解:从一个结构的成员指针找到其容器的指针。
下面我们逐步分析这个宏是怎么展开的,以list_entry(list,struct task_struct,sibling)为例:
预处理后是((task_struct *)((char *)(list)-(unsigned long)(&((task_struct *)0)->sibling)))
第一步:
((task_struct *)0)->sibling
先把“0”强制转化为task_struct型指针,则该指针一定指向“0”(数据段基址)。
因为指针是“ task_struct *”型的,所以可取到以“0”为基地址的一个task_struct型变量sibling域的地址。
那么这个地址也就等于sibling域到结构体基地址的偏移字节数。
第二步:
((task_struct *)((char *)(list)-(unsigned long)(&((task_struct *)0)->sibling)))
(char*)(list)使指针的加减步长为一字节,(unsigned long)(&((task_struct *)0)->sibling)使刚才的
偏移强制转化为unsigned long型以实现兼容,而这二者相减即为task_struct型变量的结构体的地址,转化为
tack_struct*型即可
阅读(1641) | 评论(0) | 转发(0) |