linux中container_of(ptr, type, member)
2015-10-10 10:48
375 查看
在linux下很多地方使用了list_entry(链表结构实现), rb_entry(红黑树实现), sb_entry(文件系统实现)之类的结构,原因是因为linux内核在实现链表,红黑树这一类基本的数据结构的时候都是最简单化的实现,如果要使用这些基本数据结构,就需要在自己定义的数据结构中包含这类最基本的数据结构。
而我们在使用中往往需要返回包含这类基本数据结构的大结构本身,这时候我们就需要用到list_entry,rb_entry这些宏的实现,而这些宏本身却都是基于一个叫container_of的宏的实现,其解释如下:
#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)
它的作用是:设ptr是某个type类型结构中的member成员变量的地址,该宏的结果是得到该type的地址。即有结构中成员变量的地址得到结构的地址。
1.ptr为物理地址,其类型和member类型一致,最终使用typeof(
((type
*)0)->member
)
由编译器自动返回member的类型
2.type为包含member成员的结构体
3.offsetof(type,member)为member成员在type结构体中的偏移值,大小范围0~sizeof(type)字节
(因为以0地址为type类型数据结构的起始地址)
4.ptr-
offsetof()就等于包含该ptr的type结构体父变量的物理起始地址,强制转换为(type*).
5.
http://www.ibm.com/developerworks/cn/linux/kernel/l-chain/
注:转载出自:http://blog.chinaunix.net/uid-24549279-id-71354.html
而我们在使用中往往需要返回包含这类基本数据结构的大结构本身,这时候我们就需要用到list_entry,rb_entry这些宏的实现,而这些宏本身却都是基于一个叫container_of的宏的实现,其解释如下:
#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)
它的作用是:设ptr是某个type类型结构中的member成员变量的地址,该宏的结果是得到该type的地址。即有结构中成员变量的地址得到结构的地址。
1.ptr为物理地址,其类型和member类型一致,最终使用typeof(
((type
*)0)->member
)
由编译器自动返回member的类型
2.type为包含member成员的结构体
3.offsetof(type,member)为member成员在type结构体中的偏移值,大小范围0~sizeof(type)字节
(因为以0地址为type类型数据结构的起始地址)
4.ptr-
offsetof()就等于包含该ptr的type结构体父变量的物理起始地址,强制转换为(type*).
5.
((size_t) &((TYPE *)0)->MEMBER)表示当结构TYPE为0时其成员MEMBER的地址,即位移量。
关于linux内核中的链表数据结构,推荐看一篇文章: 《深入分析 Linux 内核链表》,文章链接是:
http://www.ibm.com/developerworks/cn/linux/kernel/l-chain/
注:转载出自:http://blog.chinaunix.net/uid-24549279-id-71354.html
相关文章推荐
- 程序的链接和装入及Linux下动态链接的实现
- linux编程段错误及调试方法
- linux终端的概念
- Linux进程与线程之一
- Linux文件I/O之二
- linux 静态库、共享库
- Linux文件I/O之一
- linux 标准IO缓冲机制探究
- Linux命令学习之三
- Linux命令学习之一
- Linux命令学习之二
- linux调试gdb
- linux zip 文件夹
- linux编译makefile
- linux expr命令字符串操作
- CentOS6.6重设root密码(单用户模式)
- Linux里如何查找文件内容
- Linux系统参数(待更新)
- 如何在linux系统中设置静态ip地址
- Linux内核学习资料