container_of
关于 container_of(…)的说明
1.首先看看下面这两个宏的定义
#define offsetof(TYPE, MEMBER) ((size_t) &((TYPE *)0)->MEMBER)
#define container_of(ptr, type, member) ({
const typeof(((type )0)->member)__mptr = (ptr);
(type *)((char *)__mptr - offsetof(type, member)); })
2再说说这两个宏的作用.
首先需要说明的是,在C语言中指针的使用灵活度很大,假如给你一个0x12345678的地址,如果把它转换为(char *)0x12345678,那么这个地址指向的内存中就可以用来存在char的字符,如果转换为(int * )0x12345678,那么这个地址就可用来存在int的数据,如果装换为我们自己的结构体(struct wak * )0x12345678,那么这个地址就可用来存在struct wak的数据。
下面来看看宏定义中的内容
((TYPE *)0):把0地址转换成TYPE类型的地址,那么0地址就可以存放TYPE类型的数据了.
&((TYPE *)0)->MEMBER):返回0地址处存放的TYPE中的一个为MEMBER的成员的地址,显然TYPE是个结构体类型.由于TYPE的数据是从0地址存放的,所以返回的MEMBER的成员的地址其实就是MEMBER到这个结构体的首部的长度。这个很好理解吧,这也是这个宏的精妙的地方.
所以#define offsetof(TYPE, MEMBER) ((size_t) &((TYPE *)0)->MEMBER):获取结构体成员相对于结构体首部的偏移.
再看看下面这个宏的内容
const typeof(((type )0)->member)__mptr = (ptr),其中 typeof(((type )0)->member)__mptr其实是定义了一个__mptr的指针变量,变量的类型就是member的类型,其中使用typeof()就是为了获得member的类型,然后__mptr就指向了ptr了.
(type *)((char *)__mptr - offsetof(type, member)):__mptr是个指针,其实就是地址,然后减去member到type的偏移后,__mptr就指向了type的首部了,最后把__mptr的地址转换为type在返回这个地址。
所以#define container_of(ptr, type, member) ({
const typeof(((type )0)->member)__mptr = (ptr);
(type *)((char *)__mptr - offsetof(type, member)); }):获取ptr所在结构体的首地址.
现在其实应该清楚了吧,这两个宏是有关联的,一个用来获取偏移,一个用来获取对应的结构体的首地址.
文章最后发布于: 2018-11-17 16:46:59
相关阅读
霍夫变换是图像处理中从图像中识别几何形状的基本方法之一,应用很广泛,也有很多改进算法。主要用来从图像中分离出具有某种相同特征
Dockerfile 是一个文本格式的配置文件,用户可以使用Dockerfile来快速创建自定义镜像。 指令集的功能说明 指令
WinKawaks详尽使用说明 作者:飞雪 这篇文章是飞雪大人的作品,本来想自己写一篇来着。但想想自己怎么也不如飞雪写得好,不如把原文转
阴阳师为崽而战第二期应援对决阶段玩法说明,阴阳师第二期为崽而战应援对决阶段玩法说明带给大家,作为快速获得积分和勋章的阶段,看看
offsetof() 和 container_of() 两个宏定义在Linux内核中很常见。我们在应用程序编程时可能也需要用到,因此可以把这两个宏定义copy