container_of

在linux内核中经常遇到container_of宏,定义如下:

#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)


container_of(ptr, type, member) 是假设我们知道了一个type类型的结构体,拥有member对象,我们需要根据指向member对象的指针ptr定位到指向type类型的指针。

比如:

struct type{

int a;

double member;

};

struct ptr tmp;

double * ptr = &tmp.b;

那么我们现在就是根据指针ptr,类型type,成员member,找到指向type本身的指针。


该宏的含义如下:

假设我们定义一个类型为type的变量,如果其地址为0,那么成员member的地址就是成员member在type中的偏移。那么成员member的实际位置减去在结构体中的偏移就是该结构体的地址。主要的步骤是第二步:(type *)( (char *)__mptr - offsetof(type,member) ; 这里的__mptr 是同等于传递进来的ptr的。

由于这是宏,为了避免使用宏,扩展之后的问题,没有直接使用传递进来的指针直接进行加减。而是定义了一个变量指向它。由于我们不知道成员member的类型,所以第一步使用了一个typeof来获得类型,然后定义这样的一个变量指向传递来的指针。 const typeof( ((type *)0)->member ) *__mptr = (ptr); 

这里比较有技巧的就是((type *)0)->member;

还有一个要注意的地方,就是第二步算减法的时候,定义要讲第一个指针强制类型转换为char *,这样指针之间的相减才是以char为单位的,而不是以member类型为单位。


 


  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值