发新话题
打印

list_entry()宏

list_entry()宏

#define list_entry(ptr, type, member) \
        ((type *)((char *)(ptr)-(unsigned long)(&((type *)0)->member)))
ptr是指向list_head类型链表的指针,type为一个结构,而member为结构type中的一个域,类型为list_head,这个宏返回指向type结构的指针。在内核代码中大量引用了这个宏,因此,搞清楚这个宏的含义和用法非常重要。

在我的《深入分析Linux内核源代码》中有以上叙述,学生们在阅读的过程中,对其进行了进一步的解析,过程如下:
   
设有如下结构体定义:
typedef struct xxx
{
……(结构体中其他域,令其总大小为size1)
type1 member;
……(结构体中其他域)
}type;


定义变量:
type a;
type * b;
type1 * ptr;
执行:
ptr=&(a.member);
b=list_entry(ptr,type,member);
则可使b指向a,得到了a的地址。


如何做到的呢?


先看&((type *)0)->member:
把“0”强制转化为指针类型,则该指针一定指向“0”(数据段基址)。因为指针是“type *”型的,所以可取到以“0”为基地址的一个type型变量member域的地址。那么这个地址也就等于member域到结构体基地址的偏移字节数。





再来看 ((type *)((char *)(ptr)-(unsigned long)(&((type *)0)->member))):
(char *)(ptr)使得指针的加减操作步长为一字节,(unsigned long)(&((type *)0)->member)等于ptr指向的member到该member所在结构体基地址的偏移字节数。二者一减便得出该结构体的地址。转换为(type *)型的指针,大功告成。


大家还可以就此进一步讨论~



[ 本帖最后由 陈莉君 于 2007-12-27 20:52 编辑 ]
透析真谛,似拨云穿雾;共享智慧,如春风沐浴
http://www.kerneltravel.net
陈老师,图片显示不出来。
http://scauos.cn
*nix学习捷径
项目孵化,资源整合,共享并汇聚知识与人才
陆续推出增值服务,就业前后的最佳伙伴
中国第一个生物信息学Wiki
世界第一个BioPerl中文百科
打造生物信息学系统生物学信息安全学高规格国际交流平台
http://groups.google.com/group/linuxerfamily/web/一个宏

把上面的链接包括“一个宏”拷贝到地址栏中查看

[ 本帖最后由 陈莉君 于 2007-12-29 14:35 编辑 ]
透析真谛,似拨云穿雾;共享智慧,如春风沐浴
http://www.kerneltravel.net
发新话题