Chinaunix首页 | 论坛 | 博客
  • 博客访问: 14281
  • 博文数量: 10
  • 博客积分: 275
  • 博客等级: 二等列兵
  • 技术积分: 110
  • 用 户 组: 普通用户
  • 注册时间: 2011-07-04 16:18
文章分类
文章存档

2011年(10)

我的朋友

分类: 嵌入式

2011-07-12 16:36:29

为了理解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的地址在数值上就等于偏移量。
阅读(484) | 评论(0) | 转发(1) |
给主人留下些什么吧!~~