Chinaunix首页 | 论坛 | 博客
  • 博客访问: 367307
  • 博文数量: 26
  • 博客积分: 3020
  • 博客等级: 中校
  • 技术积分: 855
  • 用 户 组: 普通用户
  • 注册时间: 2006-03-27 17:08
文章分类

全部博文(26)

文章存档

2011年(2)

2010年(8)

2009年(16)

我的朋友

分类: LINUX

2009-09-08 19:36:10

 #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*型即可
阅读(1611) | 评论(0) | 转发(0) |
给主人留下些什么吧!~~