container_of在kernel.h中的声明:
/**
* container_of - cast a member of a structure out to the containing structure
* @ptr: the pointer to the member.
* @type: the type of the container struct this is embedded in.
* @member: the name of the member within the struct.
*
*/
#define container_of(ptr, type, member) ({ /
const typeof( ((type *)0)->member ) *__mptr = (ptr); /
(type *)( (char *)__mptr - offsetof(type,member) );})
container_of在Linux Kernel中的应用非常广泛,它用于获得某结构中某成员的入口地址.
#define offsetof(TYPE, MEMBER) ((size_t) &((TYPE *)0)->MEMBER)
TYPE* 0一个假想TYPE类型struct,MEMBER是该struct中的一个成员. 由于该struct的基地址为0, MEMBER的地址就是该成员相对与struct头地址的偏移量.
关于typeof,这是gcc的C语言扩展保留字,用于声明变量类型.
const typeof( ((type *)0->member ) *__mptr = (ptr);意思是声明一个与member同一个类型的指针常量 *__mptr,并初始化为ptr.
(type *)( (char *)__mptr - offsetof(type,member) );意思是__mptr的地址减去member在该struct中的偏移量得到的地址, 再转换成type型指针.该指针就是包含member结构体的地址了,类型为type,也就是你传进去的type值.
验证代码:
#include <stdio.h>
struct fox {
unsigned int length;
unsigned long weigth;
};
#define container(p, type, member) ({ \
typeof(((type *)0)->member)* sp = (p); \
(type *) ((char*)sp - (size_t)(&((type*)0)->member)); \
}) \
#define offsetof(type, member) ({ \
(size_t)(&((type *)0)->member);\
})
#define container_of(ptr, type, member) ({ \
const typeof(((type *)0)->member)*__mptr = (ptr); \
(type *)((char *)__mptr - offsetof(type, member)); })
int main(int argc, char**argv)
{
struct fox d;
d.length = 10;
d.weigth = 12.6;
struct fox *p = container(&d.weigth, struct fox, weigth);
int m = (size_t)&(((struct fox *)0)->weigth);
printf("%p \n", p);
return 0;
}
590

被折叠的 条评论
为什么被折叠?



