Chinaunix首页 | 论坛 | 博客
  • 博客访问: 1980231
  • 博文数量: 610
  • 博客积分: 11499
  • 博客等级: 上将
  • 技术积分: 5511
  • 用 户 组: 普通用户
  • 注册时间: 2008-03-12 19:27
文章分类

全部博文(610)

文章存档

2016年(5)

2015年(18)

2014年(12)

2013年(16)

2012年(297)

2011年(45)

2010年(37)

2009年(79)

2008年(101)

分类:

2012-06-05 11:49:05

原文地址:list_entry 的理解 作者:whonex

为了理解list_entry,先定义一个结构体:
struct student{
    char name[100];
    int num;
    struct list_head list;
};


原型:
#define list_entry(ptr, type, member) \
container_of(ptr, type, member)

参数:
ptr是指向struct list_head的指针
type是自己定义的struct类型,里面包含一个struct list_head类型的成员
member是一个struct list_head类型的变量

作用:在使用list的时候我们得到的时list的指针,需要通过list指针获得
自己定义的结构体变量的起始地址。

container_of(ptr, type, member)的原型:
#define container_of(ptr, type, member) ({ \
const typeof(((type *)0)->member) * __mptr = (ptr); \
(type *)((char *)__mptr - offsetof(type, member)); })

假设我们自己定义了一个student
struct student stu;
已知stu.list的指针pstu;

container_of(pstu, struct student, list)

const typeof(((type *)0)->member) * __mptr = (ptr);
解释:
定义一个指针__mptr,类型为typeof(((type *)0)->member), 初始值ptr
这里使用虚拟地址0x0,强制转换为type类型的指针(即struct student),通过
((struct student *)0)->list 获得成员list,再用typeof获得类型。

offsetof(type, member) //获取偏移量,原型在后面说明
获得member到type的偏移量,对上面的例子来说就是获得
&stu 和 &(stu.list) 之间的距离。

(type *)((char *)__mptr - offsetof(type, member));
__mptr减去偏移量即可获得stu的起始地址。

offsetof(type, member)原型:
#define offsetof(TYPE, MEMBER) ((size_t) &((TYPE *)0)->MEMBER)
解释:
使用虚拟地址0x0,强制转换为type类型的指针(即struct student);因为是从0x0开始计算,所以
MEMBER的地址在数值上就等于偏移量。
阅读(340) | 评论(0) | 转发(0) |
给主人留下些什么吧!~~