转:container_of分析 研究内核的博客
源地址: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的值是不确定的。
- 上一篇:offset宏的讲解
1.offset宏讲解
#define offsetof(TYPE, MEMBER) ((size_t) &((TYPE*)0)->MEMBER)
对这个宏的讲解我们大致可以分为以下4步进行讲解:
地址强制 "转换" 为 TYPE结构类型的指针;
>((TYPE *)0)->MEMBER 访问TYPE结构中的MEMBER数据成员;
>&( ( (TYPE *)0 )->MEMBER)取出TYPE结构中的数据成员MEMBER的地址;
>(size_t)(&(((TYPE*)0)->MEMBER))结果转换为size_t类型。
呢?当然不是,我们仅仅是为了计算的简便。也可以使用是他的值,只是算出来的结果还要再减去该数值才是偏移地址。来看看如下的代码:
#include<stdio.h>
#defineoffsetof(TYPE, MEMBER) ((size_t) &((TYPE *)4)->MEMBER)
struct test_struct {
int num;
char ch;
float f1;
};
int main(void)
{
printf("offsetof (struct test_struct,num)=%d\n",offsetof(struct test_struct,num)-4);
printf("offsetof (structtest_struct,ch) =%d\n",offsetof(struct test_struct,ch)-4);
printf("offsetof (struct test_struct,f1)=%d\n",offsetof(struct test_struct,f1)-4);
return 0;
}
运行结果为:
jibo@jibo-VirtualBox:~/cv_work/work/list/offset $ ./main
offsetof (struct test_struct,num) =0
offsetof (struct test_struct,ch) =4
offsetof (struct test_struct,f1) =8
。
二.举例体会offsetof宏的使用:
#include<stdio.h>
#defineoffsetof(TYPE, MEMBER) ((size_t) &((TYPE *)0)->MEMBER)
struct test_struct {
int num;
char ch;
float f1;
};
int main(void)
{
printf("offsetof(struct test_struct,num) =%d\n",offsetof(struct test_struct,num));
printf("offsetof (structtest_struct,ch) =%d\n",offsetof(struct test_struct,ch));
printf("offsetof (struct test_struct,f1)=%d\n",offsetof(struct test_struct,f1));
return 0;
}
执行结果为:
jibo@jibo-VirtualBox:~/cv_work/work/list/offset $ ./main
offsetof (struct test_struct,num) =0
offsetof (struct test_struct,ch) =4
offsetof (struct test_struct,f1) =8
转:container_of分析 研究内核的博客的更多相关文章
- Linux内核分析第一周学习博客 --- 通过反汇编方式学习计算机工作过程
Linux内核分析第一周学习博客 通过反汇编方式学习计算机工作过程 总结: 通过这次对一个简单C程序的反汇编学习,我了解到计算机在实际工作工程中要涉及大量的跳转指针操作.计算机通常是顺序执行一条一条的 ...
- Linux内核分析第二周学习博客——完成一个简单的时间片轮转多道程序内核代码
Linux内核分析第二周学习博客 本周,通过实现一个简单的操作系统内核,我大致了解了操作系统运行的过程. 实验主要步骤如下: 代码分析: void my_process(void) { int i = ...
- angular源码分析 摘抄 王大鹏 博客 directive指令及系列
链接地址:http://www.cnblogs.com/web2-developer/p/angular-14.html $compile的功能:将一个html字符串或者一个DOM进行编译,返回一个链 ...
- core dump + LINUX 内核系列博客
参考:http://www.cnblogs.com/ahuo/category/72819.html http://blog.csdn.net/tenfyguo/article/details/815 ...
- Linux内核总结博客 20135332武西垚
http://www.cnblogs.com/wuxiyao/p/5220677.htmlhttp://www.cnblogs.com/wuxiyao/p/5247571.htmlhttp://www ...
- LINUX 内核学习博客
http://www.cnblogs.com/yjf512/category/385367.html
- 我的Android进阶之旅------>经典的大牛博客推荐(排名不分先后)!!
本文来自:http://blog.csdn.net/ouyang_peng/article/details/11358405 今天看到一篇文章,收藏了很多大牛的博客,在这里分享一下 谦虚的天下 柳志超 ...
- 一步步开发自己的博客 .NET版(3、注册登录功能)
前言 这次开发的博客主要功能或特点: 第一:可以兼容各终端,特别是手机端. 第二:到时会用到大量html5,炫啊. 第三:导入博客园的精华文章,并做分类.(不要封我) 第四:做 ...
- hexo框架-next主题-github搭建个人博客
IT`huhui 的前言录 我在GITHUB的个人站点:http://ithuhui.cn 这里遇到的很多问题都是亲身解决后写的.还有遇到不懂可以邮件M我 在这里要感谢浮生志的博客教程,很多我一开始不 ...
随机推荐
- Android中自己定义一个shade.xml
自己定义一个shade: <shape> <!-- 实心 --> <solid android:color="#ff9d77"/> <!- ...
- excrt——cf687b
excrt的理解 问对于方程组x = ai % ci 的 通解 x+tM, (x+tM) % k 是否有唯一值 看tm%k是否==0即可 #include<cstdio> #include ...
- noip历年试题
noip2018 铺设道路 货币系统 赛道修建 一眼贪心.随便实现. 旅行 环套树枚举删除环上哪条边. 填数游戏 找规律,这谁会啊. 保卫王国 动态Dp,去问这位神仙. noip2017 小凯 ...
- delphi 文件分割与合并
流的使用分割与合并文件的函数 unit Unit1; interface uses Windows, Messages, SysUtils, Variants, Classes, Graphics, ...
- [CQOI2014]数三角形 题解(找规律乱搞)
题面 其实这道题不用组合数!不用容斥! 只需要一个gcd和无脑找规律(滑稽 乍一看题目,如果单纯求合法三角形的话情况太多太复杂,我们可以从局部入手,最终扩展到整体. 首先考虑这样的情况: 类似地,我们 ...
- [bzoj2729][HNOI2012]排队 题解 (排列组合 高精)
Description 某中学有 n 名男同学,m 名女同学和两名老师要排队参加体检.他们排成一条直线,并且任意两名女同学不能相邻,两名老师也不能相邻,那么一共有多少种排法呢?(注意:任意两个人都是不 ...
- 关于RF做自动化大致流程的梳理
RF只是一个框架,类似于单元测试框架,可以实现对用例的有效管理.结合其它第三方库,可以进行,接口,数据库,APP的自动化测试.结合JENKINS,还可以进行有效的持续集成. 本文不讲调用第三方库的哪些 ...
- 互斥锁Demo
#include <stdio.h> #include <pthread.h> pthread_t work1Id; pthread_t work2Id; ; ; pthrea ...
- yang文件语法格式
前言 NETCONF(Network Configuration Protocol),该协议的配置功能非常强大,同时兼顾监控和故障管理,安全验证和访问控制,得到业界的一致认可,被广泛用来配置网络 NE ...
- winform界面设计
http://www.cnblogs.com/wuhuacong/ 这位大师给了我指导方向 http://officeribbon.codeplex.com 提供了ribbon界面的控件 动态web ...