container_of()宏

container_of()宏在操作内核标准链表时很有用,也是内核提供的标准方法之一,其他的大多数链表操作都依赖这个宏.

这个宏用于获得一个结构(成员)的父结构体的入口地址.

因为C语言在编译的时候,结构体的地址就由ABI确定下来了, 这才有了下面的实现:

#define offsetof(TYPE, MEMBER)  ((size_t) &((TYPE *)0)->MEMBER)

/* type:父结构体的类型
 * member:子结构体在父结构体中的域名
 * ptr:指向member的指针
 */

#define container_of(ptr, type, member)   ({\
const typeof((type *)0)->member) * __mptr = (ptr);\
(type *)((char *)__mptr - offsetof(type, member));})

分析如下:

1>检查结构+存放member指针:

const typeof((type *)0)->member) * __mptr = (ptr);
假设从0开始存放的是type结构体

获取member的类型

定义一个member类型的指针__mptr, 并把ptr赋值给他(提前知道的)

这一句同时也检查了,type结构体中是否真的包含member域

2>计算member在type结构体中的偏移:

((size_t) &((TYPE *)0)->MEMBER)
假设0地址存放了一个TYPE类型的结构体

那么MEMBER的地址就是MEMBER在TYPE结构体中的偏移

3>得到父结构的入口地址, 并以"(type *)"返回:

(type *)((char *)__mptr - offsetof(type, member));
__mptr的地址减去它在父结构体中的偏移,就是父结构的入口地址了.


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

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值