container_of

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;
}


你可能感兴趣的:(container_of)