linux内核的container_of,linux 内核 container_of() 宏函数 原理详解

container_of宏函数用于从结构体成员的指针反推出整个结构体的地址。它结合typeof和offsetof运算符工作,通过成员的相对地址计算结构体的首地址。在给定的示例中,通过成员b的地址,宏函数成功地找到了结构体TEST的首地址。这个函数在内核编程和嵌入式系统中常见,用于遍历和操作包含特定成员的结构体。
摘要由CSDN通过智能技术生成

container_of() 宏函数源码:

/**

* 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) );})

函数作用:

根据某结构体任意一个成员首地址,获得整个结构体变量的首地址。

原理:

某结构体的任意一个成员的相对地址 减去 该成员在该结构体中的绝对偏移 就是该结构体的相对首地址

实例:

struct TEST

{

int a;

char b;

float c;

};

该结构体的内存分配如下图:

12d1e41ed57f

struct TEST mTEST={10,'F',12.12};

char *pB=&mTEST.b;

假如pB地址等于0xAABBCC04,根据内存分配推断mTEST的首地址应该为:0xAABBCC00

那么container_of()如何根据pB变量获得mTEST的首地址呢?

步骤如下:

1.利用GNU C标准中的 typeof 关键字,根据结构体struct TEST的成员b,定义一个和b同类型的临时变量指针用来存储输入ptr.

const typeof(((struct TEST *)0)->b ) *__mptr = (ptr);

2.利用offsetof()获得成员变量b在结构体struct TEST中的绝对偏移量=4,而__mptr=0xAABBCC04,所以获得mTEST的首地址=0xAABBCC00

和推断一样。为什么用(char *)强制类型转换__mptr,是为了让指针__mptr按一个字节一个字节偏移,要不然会根据__mptr数据类型进行偏

移,算出来的地址就不对了。

(struct TEST *)( (char *)__mptr - offsetof(struct TEST,b) );

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值