为了理解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) |