container_of,typeof详解
来源:互联网 发布:python封装成dll 编辑:程序博客网 时间:2024/05/14 12:49
- 1.源码
- /**
- * container_of - 通过结构体的一个成员获取容器结构体的指针
- * @ptr: 指向成员的指针。
- * @type: 成员所嵌入的容器结构体类型。
- * @member: 结构体中的成员名。
- *
- */
- #define container_of(ptr, type, member) ({ \
- const typeof( ((type *)0)->member ) *__mptr = (ptr); \
- (type *)( (char *)__mptr - offsetof(type,member) );})
- 这个宏的作用,就是通过一个容器(结构体)中某个成员的指针得到指向这个容器(结构体)的指针,简单的说就是通过成员 找容器。
- #define offsetof(TYPE, MEMBER) ((size_t) &((TYPE *)0)->MEMBER)
- 2.用法
例如:
typedef struct frame {
int a;
char b;
char name[10];
} frame_t;
int main(int argc, char **argv)
{
frame_t fra, *pf;
fra.a = 1;
fra.b = 2;
snprintf(fra.name, 5, "cjz%d", 1);
pf = container_of(&fra.a, frame_t, a);
printf("fra.a = %d, fra.b = %d, fra.name = %s\n", fra.a, fra.b, fra.name);
return 0;
}参考:http://blog.csdn.net/cuijianzhongswust/article/details/82493523.详解
先分析一下这个 宏的运行机理:
#define offsetof(TYPE, MEMBER) ((size_t) &((TYPE *)0)->MEMBER)
一共4步
1. ( (TYPE *)0 ) 将零转型为TYPE类型指针;
2. ((TYPE *)0)->MEMBER 访问结构中的数据成员;
3. &( ( (TYPE *)0 )->MEMBER )取出数据成员的地址;
4.(size_t)(&(((TYPE*)0)->MEMBER))结果转换类型。巧妙之处在于将0转 换成(TYPE*),结构以内存空间首地址0作为起始地址,则成员地址自然为偏移地址;注释:
1.要将地址赋给指针, int *p = 0x12345678是不对的 。正确的方式应为:int *p = (int *) 0x12345678。在大多数计算机中,内存地址确实是以无符号整型数来表示的,而且多以16进制表示,但我们在C语言中不能用整型数去表示地址,只能用指针常量来表示,因为它是被用来赋给一个指针的。
对于这个赋值问题还可以换一个角度去理解,在C语言中,使用赋值操作符时,赋值操作符左边和右边的表达式类型应该是相同的,如果不是,赋值操作符将试图把右边表达式的值转换为左边的类型。所以如果写出int *p = 0x12345678 ; 这条语句编译器会报错:'=' : cannot convert from ' const int ' to ' int * ' ,因为赋值操作符左边和右边的表达式的类型应该相同,而0x12345678是int型常量,p是一个指向int型的指针,两者类型不同,所以正确的方式是:int *p = (int *) 0x12345678 ;
故((TYPE*)0)是将地址为0转换成TYPE*型指针。即地址0处存放指向TYPE类型数据的地址。则((TYPE*)0)->MEMBER指向TYPE类型数据的成员MEMBER.((TYPE*)0)->MEMBER相当于(*((TYPE*)0)).MEMBER.
参考:http://blog.chinaunix.net/uid-28458801-id-4200573.html
- (1)const typeof( ((type *)0)->member ) *__mptr = (ptr); typeof即将参数*_mptr定义为((type *)0)->member类型,即复制ptr。定义一个中间变量__mptr,它等于提供给宏的参数ptr,也就是指向某个成员的指针。这个中间变量的命名意义是:"__"代表内部使用,内核编程中常常这么做;“m”代表middle。
- 为了避免对 ptr及prt指向的内容造成破坏,这里不直接使用 ptr 而要多多加一个__mptr。
(2)(type *)( (char *)__mptr - offsetof(type,member) );这行代码的作用是通过中间变量__mptr(指向某个成员的指针)减去这个成员在容器(结构体)中的偏移来得到指向容 器(结构体)的指针。 把__mptr转换成 char *类型,因为offsetof得到的偏移量是以字节为单位。两者相减得到结构体的起始位置,再强制转 换成type类型。参考:http://blog.chinaunix.net/uid-20543672-id-3205315.html
- container_of,typeof详解
- offsetof typeof container_of 浅析
- container_of,offsetof,与typeof
- linux kernel typeof container_of
- typeof、offsetof、container_of
- offsetof ,container_of ,typeof 用法
- typeof、offsetof、container_of的解释
- container_of详解
- container_of详解
- container_of 详解
- container_of详解
- container_of详解
- container_of 详解
- container_of 详解
- container_of()详解
- Container_of详解
- container_of 详解
- The Magical container_of() Macro and typeof()
- 面试题 两个表字段相同更新表A
- IMX6Solo启动流程-从Uboot到kernel 下
- js原生无缝滚动demo
- SQL SERVER 与ACCESS、EXCEL的数据转换
- Android NDK学习 <三> Android.mk实例和NDK实用技巧
- container_of,typeof详解
- Case - Cass Assign
- java 匿名内部类 抽象类跟接口可以直接New出来啊~~
- Google 开源项目风格指南 (中文版)
- JNI编程指南-第三章 基本类型、字符串、数组
- Android NDK学习 <四> Application.mk简介
- 学习C#小问题积累
- HDU 5414 CRB and String( 2015 Multi-University Training Contest 10)
- HDU 3577 Fast Arrangement(线段树功能:区间更新,查询区间的最大覆盖次数)