首先来个简单版本

 /* given a pointer @ptr to the field @member embedded into type (usually
* struct) @type, return pointer to the embedding instance of @type. */
#define container_of(ptr, type, member) \
((type *)((char *)(ptr)-(char *)(&((type *))->member)))

  作用:主要用于结构体,给定一个指针ptr指向一个结构体type的实例的成员member,返回此结构体实例的首地址,也就是这个结构体实例的指针,啰嗦一堆,还不如一个实例:

 typedef struct ABC{
char a;
char b;
int c;
}ABC; int main(int argc, const char *argv[])
{
ABC ins; printf("%p\n", container_of(&ins.c, ABC, c));
printf("%p\n", &ins);
return ;
}

  打印出来的值应该是相等的,都是结构体ins的首地址。我们将宏展开:

 container_of(&ins.c, ABC, c);
//展开后
((ABC *)((char *)(&ins.c)-(char *)(&((ABC *))->c)));

  在减号的2边分别是2个部分,前面: (char *)(&ins.c),也就是指向ins的成员c的指针,后面:(char *)( &(((ABC *)0)->c))就是成员c相对于结构体ABC指针的偏移,比如在本例中:

成员c的指针(&ins.c)减去成员c的偏移(offset)那么得到的就是结构体ins首地址。如果我只知道某个结构体成员的指针值,那么通过container_of宏就可以得到结构体指针,那么就可以随意访问它的任意一个成员。

升级版:

 #define offsetof(typ,memb) ((long)(long_ptr_t)((char *)&(((typ *)0)->memb)))
#define container_of(ptr, type, member) ({ \
const typeof( ((type *))->member ) *__mptr = (ptr); \
(type *)( (char *)__mptr - offsetof(type,member) );})

升级版有何改进呢?我就我知道的总结下:

1.const修饰,确保传入的ptr指向不被修改。2.使用了一个中间变量,定义一个成员member类型的变量指针__mptr,然后将ptr赋值给它。为何要这样?就是为了以防万一,如果你搞错了传的指针不是指向成员member的,那么编译器至少会有个警告。

3.offset宏使用(long)(long_ptr_t)2个数据类型作强转我没看太懂,(long long )64位?一个成员的偏移有可能超过32位?倒是__mptr这个地址值可能超过32位(寻址超过4G)。不解。

参考:

  http://broken.build/2012/11/10/magical-container_of-macro/

  linux 3.13.0内核。

linux内核宏container_of的更多相关文章

  1. linux内核宏container_of前期准备之gcc扩展关键字typeof

    typeof基本介绍 typeof(x) 这是它的使用方法,x可以是数据类型或者表达式.它的作用时期和sizeof类似,就是它是在编译器从高级语言(如C语言)翻译成汇编语言时起作用,这个很重要,稍后会 ...

  2. Linux内核中container_of宏的详细解释

    上一节拒绝造轮子!如何移植并使用Linux内核的通用链表(附完整代码实现)我们在分析Linux内核链表的时候注意到内核在求解结构体偏移的时候巧妙的使用了container_of宏定义,今天我们来详细剖 ...

  3. Linux内核宏DEVICE_ATTR使用

    1.前言 在Linux驱动程序编写中,使用DEVICE_ATTR宏,可以定义一个struct device_attribute设备属性,并使用sysfs的API函数,便可以在设备目录下创建出属性文件, ...

  4. linux内核代码container_of

    它的作用显而易见,那就是根据一个结构体变量中的一个域成员变量的指针来获取指向整个结构体变量的指针. typedef unsigned int __kernel_size_t; typedef __ke ...

  5. Linux内核中container_of函数详解

    http://www.linuxidc.com/Linux/2016-08/134481.htm

  6. linux内核中链表代码分析---list.h头文件分析(一)【转】

    转自:http://blog.chinaunix.net/uid-30254565-id-5637596.html linux内核中链表代码分析---list.h头文件分析(一) 16年2月27日17 ...

  7. (十)Linux内核中的常用宏container_of

    Container_of在Linux内核中是一个常用的宏,用于从包含在某个结构中的指针获得结构本身的指针,通俗地讲就是通过结构体变量中某个成员的首地址进而获得整个结构体变量的首地址. Containe ...

  8. Linux内核中的常用宏container_of

    Container_of在Linux内核中是一个常用的宏,用于从包含在某个结构中的指针获得结构本身的指针,通俗地讲就是通过结构体变量中某个成员的首地址进而获得整个结构体变量的首地址. Containe ...

  9. 嵌入式C语言自我修养 04:Linux 内核第一宏:container_of

    4.1 typeof 关键字 ANSI C 定义了 sizeof 关键字,用来获取一个变量或数据类型在内存中所占的存储字节数.GNU C 扩展了一个关键字 typeof,用来获取一个变量或表达式的类型 ...

随机推荐

  1. mysql启动报错:Starting MySQL...The server quit without updating PID file

    在mysql的data目录下误删除了mysql-bin.000001,mysql-bin.000002等文件,但是没有删除mysql-bin.index文件,此时启动mysql就会报错: Starti ...

  2. Hibernate之映射文件中索引及约束的使用

    1.添加索引: 在一对多的关系中,在多的一方会产生一个外键,这个外键没有自动 添加索引,当存在从一的一端产生对多的一端的查询时,有可能会在多的一端造成全表查询问题,数据量巨大时会产生严重的性能问题.可 ...

  3. 总结一下SQL的全局变量

    SQL Server 2008中的全局变量及其用法 T-SQL程序中的变量分为全局变量和局部变量两类,全局变量是由SQL Server系统定义和使用的变量.DBA和用户可以使用全局变量的值,但不能自己 ...

  4. Linux 学习手记(5):使用Vim文本编辑器

    Vim是从vi发展而来的文本编辑器.vi是Linux及类Unix系统中主流的命令行文本编辑器,Vim 除了对vi功能上进行了加强,还加入了对GUI的支持.绝大多数的Linux系统上均安装了vim,vi ...

  5. Linux_Centos中搭建nexus私服

    1.在Linux下搭建Nexus私服 1).下载并且解压      下载  nexus-2.11.2-03-bundle.zip      unzip nexus-2.11.2-03-bundle.z ...

  6. android 不一样的学习记录

    http://blog.csdn.net/innost/article/details/48228651 ( 深入理解Android 之 Gradle) 介绍:这篇文章篇幅较长,需要有时间并足够有耐心 ...

  7. 关于一个js连续赋值问题之我见(词略穷,见谅)

    前几天在搜索面试题时发现了这么一段代码,执行完后感觉完全不与所想的一样 var a = { n : 1 }; var b = a; a.x = a = {n : 2}; console.log(a.x ...

  8. 通过FTP连接Azure上的网站

    下载发布文件 使用记事本(或其他文本工具)打开 找到ftp连接地址以及用户名.密码 使用ftp工具进行连接 输入相应参数,连接即可

  9. Android Service获取当前位置(GPS+基站)

    需求详情:1).Service中每隔1秒执行一次定位操作(GPS+基站)2).定位的结果实时显示在界面上(要求得到经度.纬度)技术支持:1).获取经纬度通过GPS+基站获取经纬度,先通过GPS来获取, ...

  10. android XMl 解析神奇xstream 二: 把对象转换成xml

    前言:对xstream不理解的请看:android XMl 解析神奇xstream 一: 解析android项目中 asset 文件夹 下的 aa.xml 文件 1.Javabeen 代码 packa ...