揭开linux内核中container_of的神秘面纱
来源:互联网 发布:淘宝宝贝标题关键词 编辑:程序博客网 时间:2024/05/16 07:58
在linux 内核中有一个大名鼎鼎的宏container_of(),这个宏是用来干嘛的呢?我们先来看看它在内核中是怎样定义的。
呵呵,乍一看不知道是什么东东。
我们先来分析一下container_of(ptr,type,member),这里面有ptr,type,member分别代表指针、类型、成员。看一个例子:
Struct test
{
int i;
int j;
char k;
};
Struct test temp;
现在呢如果我想通过temp.j的地址找到temp的首地址就可以使用container_of(&temp.j,struct test,j);
现在我们知道container_of()的作用就是通过一个结构变量中一个成员的地址找到这个结构体变量的首地址。
下面来看看比较复杂的内容:
我们用上面的struct test张展一下
Const typeof(((struct test *)0)->j) * __mptr = (&temp.j);
其中,typeof是GNU C对标准C的扩展,它的作用是根据变量获取变量的类型。因此,上述代码的作用是首先使用typeof获取结构体成员j的类型为int,然后顶一个int指针类型的临时变量__mptr,并将结构体变量中的成员的地址赋给临时变量__mptr。
(struct test *)((char *)__mptr - offsetof(struct test,j));
接着我们来看一下offsetof(struct test,j),他在内核中如下定义
展开(size_t)&((struct test *)0)->j,这是什么东东?
一开始也不明白,这里要感谢曹忠明老师的热心帮助,一语惊醒梦中人,呵呵,可以是这样理解。
其中size_t是整型,那么我们可以知道最终的结果是一个整形值,也就是j相对于0地址的偏移量。也许现在你会问,整出这么个玩意干嘛,下面看个列子:
程序运行结果:
发现没有如果把第二个值 减去最后一个值,就能得到第一个值。
在回首一下它:
(struct test *)((char *)__mptr - offsetof(struct test,j));
是不是可以获得结构体变量temp的首地址呀,是不是太精妙了呀,linux内核中随随便便一个宏就有如此精妙,呵呵,想想对linux了解非常多的牛人,还有很长一段路。
#define container_of(ptr, type, memeber) ({ \
const typeof(((type *)0)->member) *__mptr =(ptr); \
(type *) ((char *)__mptr -offsetof(type, member));})
#define offsetof(TYPE, MEMBER) ((size_t) &((TYPE *)0)->MEMBER)
- 揭开linux内核中container_of的神秘面纱
- 揭开linux内核中container_of的神秘面纱
- 揭开linux内核中container_of的神秘面纱
- 揭开linux内核中container_of的神秘面纱
- 揭开linux内核中container_of的神秘面纱
- 揭开linux内核中container_of的神秘面纱
- 揭开linux内核中container_of的神秘面纱
- 揭开linux内核中container_of的神秘面纱
- 揭开linux内核中container_of的神秘面纱
- 揭开linux内核中container_of的神秘面纱
- 揭开linux内核中container_of的神秘面纱
- 揭开linux内核中container_of的神秘面纱
- 揭开linux内核中container_of的神秘面纱
- 揭开linux内核中container_of的神秘面纱
- 揭开Linux Proc文件系统的神秘面纱
- 揭开Linux系统内核调试器神秘面纱(上)
- 揭开Linux系统内核调试器神秘面纱(下)
- 揭开木马的神秘面纱
- Linux使用crontab运行定时任务详解
- 《MFC游戏开发》笔记二 建立工程、调整窗口
- Ext.Ajax.request与form.getForm().submit的区别
- poj2486 Apple Tree (树形dp)
- IPB帧编码顺序(解码顺序)与显示顺序
- 揭开linux内核中container_of的神秘面纱
- Erlang Binary的内部结构和分类介绍
- PRVF-00002: Could not retrieve local nodename
- 自由动态配置grid 表头,样式和数据
- 《MFC游戏开发》笔记三 游戏贴图与透明特效的实现
- 【ExtJS】终极UI-CRUD、报表、导入、导出、数据模板式导入数据
- Ubuntu小私房(3)--Grub,Burg 的使用
- 随手在网上找了一段将字节数组转换为十六进制字符串的代码,结果被坑惨了
- 《Windows核心编程》阅读小记 1