转自:http://blog.csdn.net/tigerjibo/article/details/8299589

1.container_of宏

1> Container_of在Linux内核中是一个常用的宏,用于从包含在某个结构中的指针获得结构本身的指针,通俗地讲就是通过结构体变量中某个成员的首地址进而获得整个结构体变量的首地址。
2>接口:
container_of(ptr, type, member) 
 ptr:表示结构体中member的地址
 type:表示结构体类型
 member:表示结构体中的成员
通过ptr的地址可以返回结构体的首地址
3> container_of的实现: 
#define container_of(ptr, type, member) ({      \   
 const typeof( ((type *)0)->member ) *__mptr = (ptr);    \  
  (type *)( (char *)__mptr - offsetof(type,member) );})  
其实它的语法很简单,只是一些指针的灵活应用,它分两步:
第一步,首先定义一个临时的数据类型(通过typeof( ((type *)0)->member )获得)与ptr相同的指针变量__mptr,然后用它来保存ptr的值。
说明:typeof是GNU C对标准C的扩展,它的作用是根据变量获取变量的类型《typeof关键字在linux 内核中很常见》
第二步,用(char *)__mptr减去member在结构体中的偏移量,得到的值就是整个结构体变量的首地址(整个宏的返回值就是这个首地址)。
关于offsetof的用法可参见offsetof宏的使用

2. 举例来说明container_of的使用

1>正确示例:

#include <stdio.h>
#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) );})
struct test_struct {
           int num;
          char ch;
          float f1;
  };
 int main(void)
  {
          struct test_struct *test_struct;
          struct test_struct init_struct ={12,'a',12.3};
          char *ptr_ch = &init_struct.ch;
          test_struct = container_of(ptr_ch,struct test_struct,ch);
          printf("test_struct->num =%d\n",test_struct->num);
          printf("test_struct->ch =%c\n",test_struct->ch);
          printf("test_struct->ch =%f\n",test_struct->f1);
          return 0;
  }
执行结果:
jibo@jibo-VirtualBox:~/cv_work/work/list/container_of $ ./main
test_struct->num =12
test_struct->ch =a
test_struct->ch =12.300000

2>错误示例:

#include <stdio.h> 
  #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) );}) 
   struct test_struct {
           int num;
          char ch;
          float f1;
  }; 
  int main(void)
  {
          struct test_struct *test_struct;
          char real_ch = 'A';
          char *ptr_ch = &real_ch;
          test_struct = container_of(ptr_ch,struct test_struct,ch);
          printf("test_struct->num =%d\n",test_struct->num);
          printf("test_struct->ch =%c\n",test_struct->ch);
          printf("test_struct->ch =%f\n",test_struct->f1);
          return 0;
  }
执行结果为:
jibo@jibo-VirtualBox:~/cv_work/work/list/container_of1 $ ./main
test_struct->num =0
test_struct->ch =A
test_struct->ch =0.000000
注意,由于这里并没有使用一个具体的结构体变量,所以成员num和f1的值是不确定的。

container_of分析【转】的更多相关文章

  1. container_of分析--可用good【转】

    转自:http://blog.csdn.net/tigerjibo/article/details/8299589 版权声明:本文为博主原创文章,未经博主允许不得转载. 1.container_of宏 ...

  2. 转:container_of分析 研究内核的博客

    源地址:http://blog.csdn.net/tigerjibo/article/details/8299589 2012-12-15 19:23 1636人阅读 评论(2) 收藏 举报   目录 ...

  3. Linux内核学习散知识整理

    1.container_of(ptr, type, member) 使用方法:根据指向结构体type的成员member的指针ptr,获取指向改结构体的指针 /** * container_of - c ...

  4. container_of宏定义分析---linux内核

    问题:如何通过结构中的某个变量获取结构本身的指针??? 关于container_of宏定义在[include/linux/kernel.h]中:/*_** container_of - cast a ...

  5. 内核中container_of宏的详细分析【转】

    转自:http://blog.chinaunix.net/uid-30254565-id-5637597.html 内核中container_of宏的详细分析 16年2月28日09:00:37 内核中 ...

  6. 关于container_of和list_for_each_entry 及其相关函数的分析

    Linux代码看的比较多了,经常会遇到container_of和list_for_each_entry,特别是 list_for_each_entry比较多,因为Linux经常用到链表,虽然知道这些函 ...

  7. linux内核container_of宏定义分析

    看见一个哥们分析container_of很好,转来留给自己看 一.#define offsetof(TYPE, MEMBER) ((size_t) & ((TYPE *)0)->MEMB ...

  8. 关于container_of函数分析

    #include <stdio.h> #define offset_of(type,member) ((int)&(((type *)0)->member)) #define ...

  9. 【转】container_of宏 分析

    在学习Linux驱动的过程中,遇到一个宏叫做container_of.该宏定义在include/linux/kernel.h中,首先来贴出它的代码: /** * container_of - cast ...

随机推荐

  1. Qt 5.9.1 连 MYSQL 5.7数据库

    Qt程序报错: QSqlDatabase: QMYSQL driver not loaded QSqlDatabase: available drivers: QSQLITE QMYSQL QMYSQ ...

  2. java递归方法求数组最大元素

    一直对递归写法不是很熟悉,特写一个增进理解 /** * Created by Administrator on 2017-11-01. */ public class recursion { priv ...

  3. 【BZOJ4999】This Problem Is Too Simple!(线段树)

    [BZOJ4999]This Problem Is Too Simple!(线段树) 题面 BZOJ 题解 对于每个值,维护一棵线段树就好啦 动态开点,否则空间开不下 剩下的就是很简单的问题啦 当然了 ...

  4. 【Learning】分数规划

    分数规划 ​ 分数规划是一类决策性问题.一般地,题目会要求你针对问题规划一种方案,使得其代价函数最小或最大.其中,代价函数一般是分数形式,且分子分母的构成元素一般呈现一一对应关系. 直接上例题观察:B ...

  5. Moonraker:1靶机入侵

      0x01 前言 攻击Moonraker系统并且找出存在最大的威胁漏洞,通过最大威胁漏洞攻击目标靶机系统并进行提权获取系统中root目录下的flag信息. Moonraker: 1镜像下载地址: h ...

  6. 构建工具----gradle---可能遇到的问题----Could not reserve enough space for object heap

    Could not reserve enough space for object heap 意思是 jvm的设置内存不足以运行gradle命令了. 分为两种情况,解决的方法也不同. .10/user ...

  7. struts2练习时犯的错误(2016年11月4日)

    1.Tomcat启动时报错 严重: 文档无效: 找不到语法. at (null:3:8) org.xml.sax.SAXParseException; systemId: file:/F:/Progr ...

  8. bzoj3203【sdoi2013】保护出题人

    题目描述 输入格式 第一行两个空格隔开的正整数n和d,分别表示关数和相邻僵尸间的距离.接下来n行每行两个空格隔开的正整数,第i + 1行为Ai和 Xi,分别表示相比上一关在僵尸队列排头增加血量为Ai  ...

  9. SpringMVC 使用@ResponseBody返回json 中文乱码

    这确实是个蛋疼的问题,Spring中解析字符串的转换器默认编码居然是ISO-8859-1 既然找到问题了,那就必须想办法改过来,不同版本的Spring好像方法还不一样,网上不少说的都是Spring3. ...

  10. Docker 及 nvidia-docker 使用

    Docker 基本用法 1. 安装社区版docker-ce 及 nvidia-docker2 插件 通过官网介绍的软件源的方式安装. 如果要安装nvidia-docker,由于其需要与docker-c ...