container_of宏的详细介绍与解答

本文深入解析了C语言中用于从结构体成员指针获取整个结构体指针的container_of宏,详细介绍了其内部实现原理,包括类型申明、偏移量计算等关键步骤。

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

首先,今天看到代码,接触到这个宏定义,所以有意去研究了一下:

struct hid_device *hdev = container_of(dev, struct hid_device, dev);

以上面例子来说这个宏的作用为:根据一个结构体变量中的一个域成员变量的指针来获取指向整个结构体变量的指针

/** 
* container_of - cast a member of a structure out to the containingstructure 
* @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) );})

以上参数英文的,相信能够写代码的童鞋都能看得懂的吧。下面针对这个宏我做下详细的介绍:

1.宏的最外围是   ({})    ,这个结构的作用举个例子:

 

intx=({7;1;})+2;

printf("%d\n",x);

输出的值为3,意思就是这个结构会找出最后一个定义的值来做运算,说的够直白吧?

2.宏的内部有一个typeof,这个作用就是为了申明一个类型,((type *)0)将零转化为type(这里的type是一个结构体类型)的指针类型,指向我们的结构体成员member,就是以零地址开始开始指向member。

3.那么我想问一下大家&((type *)0)->member是否可以说是member在整个结构体中的偏移量?ok,那么我就就仅仅认为((type *)0)->member仅仅只一个member类型的数据,typeof( ((type *)0)->member ) *__mptr就是说定义一个member数据类型的指针变量__mptr,等于指向member的指针变量。

4.(type *)( (char *)__mptr - offsetof(type,member) ),咋一看,offsetof不知道什么意思,ok

 

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

什么意思呢?这不就是我们刚才分析的吗?返回member的偏移量嘛,不解释!看不懂的自己把第三点再看一遍,然后告诉我你懂了!

 

5.那么前面的 (type *)( (char *)__mptr - offsetof(type,member) )整体看上去一些小伙伴还是看着吃力,有木有?ok,(char *)__mptr将__mptr转换为字符型指针,原来指向member的,减去它的偏移量,那么就得到它原本所在结构的首地址。那么回到

struct hid_device *hdev = container_of(dev, struct hid_device, dev);

该hid设备不就是为了得到hid_device的首地址 ({}) 定义的最后一个就是其返回的值,那么就是首地址。

 

 

 

 

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值