linux内核container_of宏定义分析
看见一个哥们分析container_of很好,转来留给自己看
一、#define offsetof(TYPE, MEMBER) ((size_t) & ((TYPE *)0)->MEMBER )
1. ( (TYPE *)0 ) 将零转型为TYPE类型指针;
2. ((TYPE *)0)->MEMBER 访问结构中的数据成员;
3. &( ( (TYPE *)0 )->MEMBER )取出数据成员的地址;
4.(size_t)(&(((TYPE*)0)->MEMBER))结果转换类型;
巧妙之处在于将0转换成(TYPE*),结构以内存空间首地址0作为起始地址,则成员地址自然为偏移地址。
举例说明:
#include<stdio.h>
typedef struct _test
{
char i;
int j;
char k;
}Test;
int main()
{
Test *p = 0;
printf("%p\n", &(p->k));
}
答案:00000008
自
己分析:这里使用的是一个利用编译器技术的小技巧,即先求得结构成员变量在结构体中的相对于结构体的首地址的偏移地址,然后根据结构体的首地址为0,从而
得出该偏移地址就是该结构体变量在该结构体中的偏移,即:该结构体成员变量距离结构体首的距离。在offsetof()中,这个member成员的地址实
际上就是type数据结构中member成员相对于结构变量的偏移量。对于给定一个结构,offsetof(type,member)是一个常
量,list_entry()正是利用这个不变的偏移量来求得链表数据项的变量地址。
二、container_of()
container_of() 来自\linux\kernel.h
内核中的注释:container_of - cast a member of a tructure out to the containing structure。
ptr: the pointer to the member.
type: the type of the container struct this is embedded in.
member:the name of the member within the truct.
#define container_of(ptr, type, member) ({ \
const typeof( ((type *)0)->member ) *__mptr = (ptr); \
(type *)( (char *)__mptr - offsetof(type,member) );})
自己分析:
1.(type
*)0->member为设计一个type类型的结构体,起始地址为0,编译器将结构体的起始的地址加上此结构体成员变量的偏移得到此结构体成员变
量的偏移地址,由于结构体起始地址为0,所以此结构体成员变量的偏移地址就等于其成员变量在结构体内的距离结构体开始部分的偏移量。即:&
(type *)0->member就是取出其成员变量的偏移地址。而其等于其在结构体内的偏移量:即为:(size_t)(&
((type
*)0)->member)经过size_t的强制类型转换后,其数值为结构体内的偏移量。该偏移量这里由offsetof()求出。
2.typeof( ( (type *)0)->member )为取出member成员的变量类型。用其定义__mptr指针.ptr为指向该成员变量的指针。__mptr为member数据类型的常量指针,其指向ptr所指向的变量处。
3.(char
*)__mptr转换为字节型指针。(char *)__mptr -
offsetof(type,member))用来求出结构体起始地址(为char *型指针),然后(type *)( (char *)__mptr
-offsetof(type,member) )在(type *)作用下进行将字节型的结构体起始指针转换为type *型的结构体起始指针。
4.({ })这个扩展返回程序块中最后一个表达式的值。
这就是从结构体某成员变量指针来求出该结构体的首指针。指针类型从结构体某成员变量类型转换为该结构体类型
转自:http://www.cnitblog.com/puppypyb/archive/2008/08/20/48172.aspx
linux内核container_of宏定义分析的更多相关文章
- container_of宏定义分析---linux内核
问题:如何通过结构中的某个变量获取结构本身的指针??? 关于container_of宏定义在[include/linux/kernel.h]中:/*_** container_of - cast a ...
- Linux 内核常见宏定义
我们在阅读Linux内核是,常见到这些宏 __init, __initdata, __initfunc(), asmlinkage, ENTRY(), FASTCALL()等等.它们定义在 /incl ...
- 嵌入式C语言自我修养 04:Linux 内核第一宏:container_of
4.1 typeof 关键字 ANSI C 定义了 sizeof 关键字,用来获取一个变量或数据类型在内存中所占的存储字节数.GNU C 扩展了一个关键字 typeof,用来获取一个变量或表达式的类型 ...
- linux内核中链表代码分析---list.h头文件分析(一)【转】
转自:http://blog.chinaunix.net/uid-30254565-id-5637596.html linux内核中链表代码分析---list.h头文件分析(一) 16年2月27日17 ...
- linux内核中链表代码分析---list.h头文件分析(二)【转】
转自:http://blog.chinaunix.net/uid-30254565-id-5637598.html linux内核中链表代码分析---list.h头文件分析(二) 16年2月28日16 ...
- Linux内核哈希表分析与应用
目录(?)[+] Linux内核哈希表分析与应用 Author:tiger-johnTime:2012-12-20mail:jibo.tiger@gmail.comBlog:http:// ...
- Linux内核抢占实现机制分析【转】
Linux内核抢占实现机制分析 转自:http://blog.chinaunix.net/uid-24227137-id-3050754.html [摘要]本文详解了Linux内核抢占实现机制.首先介 ...
- Linux内核--网络栈实现分析(七)--数据包的传递过程(下)
本文分析基于Linux Kernel 1.2.13 原创作品,转载请标明http://blog.csdn.net/yming0221/article/details/7545855 更多请查看专栏,地 ...
- 转载 linux内核 asmlinkage宏
转载http://blog.chinaunix.net/uid-7390305-id-2057287.html 看一下/usr/include/asm/linkage.h里面的定义:#define a ...
随机推荐
- iOS应用内跳转百度高德苹果地图
移动开发经常用到基于位置的一些导航功能,但是对于对导航功能依赖性不强的的应用,我们直接采用应用外跳转地图APP即可. 但是应用间跳转,首先需要设置白名单, 在iOS 9 下涉及到平台客户端跳转,系统会 ...
- 获取某个元素相对于视窗的位置-getBoundingClientRect
1. getBoundingClientRect用于获取某个元素相对于视窗的位置集合.集合中有top, right, bottom, left等属性. 语法:这个方法没有参数 rectObject = ...
- React-Native Navigator-this.props.navigation....
render() { return ( <View> <Text>2</Text> <Button title = "跳转到指定的页面" ...
- POJ 3368.Frequent values-处理数据+RMQ(ST)
昨天写的博客删了,占坑失败,还是先把RMQ玩的6一点再去搞后面的东西.废话少说,题解题姐姐_(:з」∠)_ Frequent values Time Limit: 2000MS Memo ...
- 网络流24T 太空飞行计划问题
题目背景 题目描述 W 教授正在为国家航天中心计划一系列的太空飞行.每次太空飞行可进行一系列商业性实验而获取利润.现已确定了一个可供选择的实验集合E={E1,E2,…,Em},和进行这些实验需要使用的 ...
- bzoj 1453: [Wc]Dface双面棋盘
1453: [Wc]Dface双面棋盘 Time Limit: 10 Sec Memory Limit: 64 MBSubmit: 617 Solved: 317[Submit][Status][ ...
- 【APIO2015】Bali Sculptures
题目描述 印尼巴厘岛的公路上有许多的雕塑,我们来关注它的一条主干道. 在这条主干道上一共有 $N$ 座雕塑,为方便起见,我们把这些雕塑从 $1$ 到 $N$ 连续地进行标号,其中第 $i$ 座雕塑的年 ...
- 如何轻松的把图片导入execl表格中
在项目中有时候会遇到往数据库中导数据的时候,往往需要把图片也一起导入execl表格中,那怎么才能把图片一块导入至execl中呢?那么今天我们就来看看怎么实现吧! 如何实现?今天我们就来用jxl和poi ...
- Java NIO中的Buffer类
Buffer 缓冲,用于批量读写数据 Buffer是一个抽象类,基本数据类型都有实现类:XxxBuffer,比如ByteBuffer.CharBuffer.IntBuffer.DoubleBu ...
- javascript --- 兼容的那些事
绑定事件 var addEvent = function( obj, type, fn ) { if (obj.addEventListener) obj.addEventListener( type ...