Linux内核——container_of
2021/9/28 7:14:15
本文主要是介绍Linux内核——container_of,对大家解决编程问题具有一定的参考价值,需要的程序猿们随着小编来一起学习吧!
在驱动过程中,一直有一个做法,就是通过,我知道的一个结构体的一个成员,那么我就可以拿到整个结构体的数据
我们也称为以小博大。
就比如字符设备驱动过程中的input_dev input_handler 和evdev_handl 这三个结构体就天天在那博来博去的。
乍一想:就是通过,我知道的一个结构体的一个成员,那么我就可以拿到整个结构体的数据。
这肯定没问题啊,我都知道一个成员了,那拿到整个结构体的数据这不是易如反掌吗?
但是真的让你去操作你会怎么操作
?
?
?
内核是定义一个宏去完成以小博大
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) 还有一个typeof的宏
typeof:这个宏就是可以获取到一个变量的类型,如我们可以这样写代码:{int a; typeof(a) b;}这段代码等价于:{int a; int b;}
接下来看一个很有意识的宏
#define offsetof(TYPE, MEMBER) ((size_t) &((TYPE *)0)->MEMBER)
首先定义了一个宏叫 offsetof
它可以传递参数(TYPE, MEMBER) 一个是结构体类型 一个是已经知道的成员
它用来替换掉了:
((size_t) &((TYPE *)0)->MEMBER)
慢慢分析
(TYPE *)0 :这个的意识就是 我把0强制转化成type的地址 那么这个就是一个type的0地址。
((TYPE *)0)->MEMBER) :这个就是我在0地址创建了一个type类型的结构体 ,我们还知道它有一个成员MEMBER;
&((TYPE *)0)->MEMBER) :这样我就拿到了以0为起始地址的type类型的结构体,的已知成员的的地址。
((size_t) &((TYPE *)0)->MEMBER) :把它强转成((size_t)型,就是偏移量了。
所以说,这个宏求出了这个成员在结构体中的偏移量,
那 我成员地址有了,偏移量有了,不就可以找到结构体首地址了吗?
这篇关于Linux内核——container_of的文章就介绍到这儿,希望我们推荐的文章对大家有所帮助,也希望大家多多支持为之网!
- 2024-11-12如何创建可引导的 ESXi USB 安装介质 (macOS, Linux, Windows)
- 2024-11-08linux的 vi编辑器中搜索关键字有哪些常用的命令和技巧?-icode9专业技术文章分享
- 2024-11-08在 Linux 的 vi 或 vim 编辑器中什么命令可以直接跳到文件的结尾?-icode9专业技术文章分享
- 2024-10-22原生鸿蒙操作系统HarmonyOS NEXT(HarmonyOS 5)正式发布
- 2024-10-18操作系统入门教程:新手必看的基本操作指南
- 2024-10-18初学者必看:操作系统入门全攻略
- 2024-10-17操作系统入门教程:轻松掌握操作系统基础知识
- 2024-09-11Linux部署Scrapy学习:入门级指南
- 2024-09-11Linux部署Scrapy:入门级指南
- 2024-08-21【Linux】分区向左扩容的方法