linux内核常用宏container_of

linux内核常用宏 container_of
定义如下:
/* linux-2.6.38.8/include/linux/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) );}) 

作用是通过结构体内成员的地址来得到结构体的首地址。
其中offsetof宏定义如下:
#define offsetof(TYPE, MEMBER) ((size_t) &((TYPE *)0)->MEMBER)
其作用是用来得到结构体内成员相对于结构体首地址的偏移量。

理解:
offsetof
#define offsetof(TYPE, MEMBER) ((size_t) &((TYPE *)0)->MEMBER)
两个宏都非常巧妙的运用的0地址,offsetof中 &((TYPE *)0)->MEMBER) 可以看成把0地址强制类型转换为TYPE*类型,然后指向MEMBER成员,&得到MEMBER成员的地址,由于TYPE地址为0,所以得到的就是MEMBER成员相对于结构体首地址的偏移量,最后用(size_t)强制类型转换为整数。

size_t 就是size type,一般用来表示一种计数,比如有多少东西被拷贝等。例如:sizeof操作符的结果类型是size_t,该类型保证能容纳实现所建立的最大对象的字节大小。 它的意义大致是“适于计量内存中可容纳的数据项目个数的无符号整数类型”。所以,它在数组下标和内存管理函数之类的地方广泛使用。使用size_t是为了在增强程序的可移植性。

container_of
有了对offsetof的理解,对container_of的理解就不难了。
第一句 const typeof( ((type *)0)->member ) *__mptr = (ptr); 使用typeof推导出 ( ((type *)0)->member ) * 得到结构体内成员的变量类型指针 ,定义为变量__mptr,地址为(ptr)。之后( (char *)__mptr - offsetof(type,member) ) 将__mptr强制类型转换为 char* 类型,目的是为了相减时能够以一字节为单位相减,C语言中指针的加减操作是以指针类型的大小为单位进行操作的。最后类型转换为(type *)得到结构体首地址。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值