container_of宏

本文详细介绍了Linux内核中常用的container_of宏。通过该宏可以根据已知的结构体成员地址找到对应的结构体地址。文章深入解析了container_of宏的实现原理,并提供了一个具体的实例帮助理解。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

container_of宏

1. 介绍

container_of宏,是linux内核中常用的一个宏。
1. 接口:container_of(ptr, type, member)
- ptr 表示结构体某个成员的地址
- type 结构体类型
- member 结构体的某个成员
2. 作用:已知结构体的某个成员地址,返回结构体的地址

2. 分析

a、原型

  • container_of
#define container_of(ptr, type, member) ({   \
const typeof(((type *)0)->member) * __mptr = (ptr); \
(type *)((char *)__mptr - offsetof(type, member)); })
  • offsetof
#ifndef offsetof
#define offsetof(TYPE, MEMBER) ((size_t) &((TYPE *)0)->MEMBER)
#endif

b、分析

第一步:首先定义一个临时的数据类型与ptr相同的变量_mptr,用来保存ptr的值。

  • typeof(((type *)0)->member)用来获取变量的类型

第二步:使用(char *)_mptr的值减去member在结构体偏移量,计算结果就是结构体变量的首地址。

  • 指针的加减要注意类型,用(char*)ptr是为了计算字节偏移。
  • ((type *)0)->member是一个小技巧。

c、实例:

/* 有结构体定义如下: */
typedef struct fuck {
    ......:
    void member;
    ......:
}type;

/* 有类型如下: */
type a;
type *point;
void *ptr;

/* 执行: */
ptr = &(a.member);
point = container_of(ptr, type, member);
  1. 先看 &((type )0)->member,把0强制转换为指针类型,则该指针一定指向”0”(数据段地址)。因为指针是”type “型的,所以可取到以”0”为基地址的一个type型变量member域的地址。那么这个地址也就等于member域到结构体基地址的偏字节数。

  2. 在看 (type ) (char )(ptr) - (unsigned long)(&((type )0)->member),(char )(ptr)使得指针的加减操作步长为一字节,(unsigned long)(&((type )0)->member)等于ptr指向的member到该member所在结构体基地址的偏移字节数。二者相减便得出该结构体的地址。转换为(type )类型即可,ok。

参考博客

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值