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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值