在linux 内核编程中,会经常见到一个宏函数container_of(ptr,type,member), 但是当你通过追踪源码时,像我们这样的一般人就会绝望了(这一堆都是什么呀?...好吧,先上container_of函数原型: #define container_of(ptr, type, member) ({ \ const typeof...(三)总结: container_of(ptr, type,member)函数的实现包括两部分: 判断ptr 与 member 是否为同意类型 计算size大小,结构体的起始地址 = (type *)...((char *)ptr - size) (注:强转为该结构体指针) 现在我们知道container_of()的作用就是通过一个结构变量中一个成员的地址找到这个结构体变量的首地址。...container_of(ptr,type,member),这里面有ptr,type,member分别代表指针、类型、成员。
在Linux 内核中,container_of 函数使用非常广,例如 Linux内核链表 list_head、工作队列work_struct中 在Linux 内核中有一个大名鼎鼎的宏container_of...我们先来分析一下container_of(ptr,type,member),这里面有ptr,type,member分别代表指针、类型、成员。...int j; char k; }; Struct test temp; 现在呢如果我想通过temp.j的地址找到temp的首地址就可以使用container_of...(&temp.j,struct test,j); 现在我们知道container_of()的作用就是通过一个结构变量中一个成员的地址找到这个结构体变量的首地址。
文章目录 回顾 问题具象化 上工具 offsetof 实例分析 container_of 实例解析 offsetof 原理 container_of 原理 参考 回顾 上一篇我们讲到内核链表和普通链表的区别...上工具 这时候,就用到了 linux 内核中提供的两个宏了 #define offsetof(TYPE, MEMBER) ((size_t) &((TYPE *)0)->MEMBER) #define container_of...container_of 宏用来在给定一个变量的结构体类型,和这个变量的某个成员的地址的条件下,计算出这个变量的地址。...我们已知 led 的一个成员变量的地址,即 led.link 的地址 我们的目的是通过 led.link 的地址求 led 的地址 struct led_dev *ptr = container_of...container_of 原理 #define container_of(ptr, type, member) ({ \ const typeof( ((type *)0)->member
【Linux API 揭秘】container_of函数详解 1、container_of函数介绍 container_of可以说是内核中使用最为频繁的一个函数了,简单来说,它的主要作用就是根据我们结构体中的已知的成员变量的地址...image-20231212195328080 下面我们看看linux是如何实现的吧 2、container_of函数实现 /** * container_of - cast a member of...函数内部涉及的相关知识了然于胸,下面我们再来看container_of,简直容易到起飞。...2.5 container_of #define container_of(ptr, type, member) ({ \ void *__mptr = (void *)(ptr); \...了解完内部完整的实现手法之后,我们也可以手码一个container_of了 :)
container_of宏 #define offsetof(TYPE, MEMBER) ((size_t) &((TYPE*)0)->MEMBER) #define container_of(ptr,...container_of宏的作用是通过结构体内某个成员变量的地址和该变量名,以及结构体类型。找到该结构体变量的地址。...举例 #define offsetof(TYPE, MEMBER) ((size_t) &((TYPE *)0)->MEMBER) #define container_of(ptr, type, member...(&stu.id,Student,id); printf("sptr=%p\n",sptr); sptr = container_of(&stu.name,Student...,name); printf("sptr=%p\n",sptr); sptr = container_of(&stu.math,Student,id);
废话不多说,今天要说的两个宏分别是offsetof和container_of,第一个宏是用来计算结构体中某个成员相对于结构体的偏移量,第二个宏是已知指向结构体某个成员的指针,来计算结构体的指针。...来看一下它们的原型: define offsetof(TYPE, MEMBER) ((int) &((TYPE *)0)->MEMBER) #define container_of(ptr, type...二、container_of 上面介绍了offsetof宏的使用,相信不是那么难理解,那么这个宏就看起来复杂多了,但是,其实只要把思路理清楚了,也不是那么复杂。
/|wc -l 710 android7.1/kernel/drivers/input$ 使用grep -rn container_of ..../|wc -l统计了下kernel/drivers/input/目录下的container_of出现的次数,一共有710次使用。...2、container_of的作用 container_of的作用的通过结构体成员变量地址获取这个结构体的地址,假设你的名字叫李光明,你还有一个弟弟叫做XXX,警察叔叔发现你弟弟XXX干了一件坏事,但是警察叔叔不知道你弟弟的名字...3、如何使用container_of container_of需要传入三个参数,第一个参数是一个指针,第二个参数是结构体类型,第三个是对应第二个参数里面的结构体里面的成员。...剖析 看完上面的几个知识点,再来看container_of这个宏就显得非常清晰了。
在Linux 内核编程中,会经常见到一个宏函数container_of(ptr,type,member)。已知结构体type的成员member的地址ptr,求结结构体type的起始地址。...container_of 在已知一个结构体的成员的名字,以及其地址的情况向,反推该结构体的首地址 offsetof 获取一个结构体成员在结构里面的偏移,结构体首地址 = 成员地址- 成员偏移 以下是一个...include #define offsetof(TYPE,MEMBER) ((int) &((TYPE *)0)->MEMBER) //为什么这样就能得到偏移 #define container_of...Pt.a = 'a'; Pt.b = 2 ; Pt.c = 4 ; Pt.d = 12.04 ; //通过container of获取结构体的首地址 pt = container_of...#define container_of(ptr, type, member) ({ \ const typeof(((type *)0)->member) *__mptr = (ptr
task_struct 内核实现 在内核中,内核通过宏定义来实现从list_head到task_struct的访问过程: // include/linux/container_of.h L10 /** * container_of...* * WARNING: any const qualifier of @ptr is lost. */ #define container_of(ptr, type, member) ({...((type *)0)->member) || \ __same_type(*(ptr), void), \ "pointer type mismatch in container_of...(ptr, type, member)),\ default: ((type *)container_of(ptr, type, member)) \ ) #endif /* _LINUX_CONTAINER_OF_H...*/ 我们首先来看container_of函数,这是一个宏定义: #define container_of(ptr, type, member) 简单来说,就是针对ptr指针,返回一个type类型的指针
通过结构体的成员获得结构体的地址,摘自kernel的一段宏,为了理解container_of,写了个例子 #include #include #include #define offsetof(TYPE, MEMBER) ((size_t) &((TYPE *)0)->MEMBER) #define container_of...,&(example->ec)); printf("%p\n",(void *)offsetof(struct example,ec)); printf("%p\n",container_of
Container_of在Linux内核中是一个常用的宏,用于从包含在某个结构中的指针获得结构本身的指针,通俗地讲就是通过结构体变量中某个成员的首地址进而获得整个结构体变量的首地址。...实现方式: container_of(ptr, type, member) ; 其实它的语法很简单,只是一些指针的灵活应用,它分两步: 第一步,首先定义一个临时的数据类型(通过typeof...1 #include 2 #define offsetof(TYPE, MEMBER) ((size_t) &((TYPE *)0)->MEMBER) 3 #define container_of...init_struct ={12,'a',12.3}; 15 char *ptr_ch = &init_struct.ch; 16 test_struct = container_of
在list_entry的定义中,我们看到出现了另外一个宏container_of。而list_entry这个宏正是通过container_of去实现的。...container_of定义在/include/linux/kernel.h中,定义如下: ? 我们发现,在container_of的定义中,又出现一个新的宏offsetof。...所以,在开始分析container_of之前,有必要先来搞清楚offsetof。 offsetof定义在/include/linux/stddef.h中,定义如下: ?...宏container_of ? 在进入container _of的世界后,我们发现这里有两个“熟悉的陌生人”,分别是typeof和“({ })”。...到这里,宏container_of就真相大白了。
2.3. container_of 2.3.1. ...定义 // ptr:结构体成员member的地址 // type:结构体类型 // member:结构体成员member #define container_of(ptr, type, ...示例 定义结构体变量: struct X x; 那么container_of(&x.b, struct X, b)的值将和&x相等。 2.4. prefetch 2.4.1. ...而在C语言中,则需要借助container_of宏:container_of(data, MyData, list); 3.2. 遍历方向 ?...作用 从list_entry的定义可以看出,它等同于container_of,即通过结构体type一个成员member的地址ptr,得到该结构本的地址。
其中,也会涉及到Linux内核中非常常用的两个经典宏定义offsetof和container_of。...内容包括: 1.Linux中的两个经典宏定义 2.Linux中双向链表的经典实现 Linux中的两个经典宏定义 倘若你查看过Linux Kernel的源码,那么你对 offsetof 和 container_of...将offsetof看作一个数学问题来看待,问题就相当简单了:已知'整体'和该整体中'某一个部分',而计算该部分在整体中的偏移 2.container_of 2.1 container_of介绍 定义:container_of...1 #define container_of(ptr, type, member) ({ \ 2 const typeof( ((type *)0)->member ) *__..., type, member) 实际上是调用的container_of宏。
其中,也会涉及到Linux内核中非常常用的两个经典宏定义offsetof和container_of。...内容包括: 1.Linux中的两个经典宏定义 2.Linux中双向链表的经典实现 Linux中的两个经典宏定义 倘若你查看过Linux Kernel的源码,那么你对 offsetof 和 container_of...将offsetof看作一个数学问题来看待,问题就相当简单了:已知'整体'和该整体中'某一个部分',而计算该部分在整体中的偏移 2.container_of 2.1 container_of介绍 定义:container_of...1 #define container_of(ptr, type, member) ({ \ 2 const typeof( ((type *)0)->member ) *__...type, member) 实际上是调用的container_of宏。
父亲是否等于自身 #define RB_CLEAR_NODE(node) (rb_set_parent(node, node)) //设置节点为空,父亲等于自身 这里需要注意的是container_of...本身也是个宏,其定义在kernel.h中: #define container_of(ptr, type, member) ({ \ const typeof( (...container_of宏取得包含ptr的数据结构的指针,具体是把ptr转化为type对象中member类型的指针,然后减去member类型在type对象的偏移量得到type对象的首地址。...修改rbtree.h:删除两个#include语句,添加stddef.h中的NULL和offsetof宏定义,添加kernel.h中的container_of宏定义。..., *parent = NULL; /* Figure out where to put new node */ while (*new) { struct mytype *this = container_of
前言: 在上期文章中,已经给大家分享过offsetof()和container_of两个宏函数,这两个宏函数在Linux内核链表里面有大量的应用,对于我们平时工作写代码有很大的帮助。...那就是: container_of(ptr, type, member) 没错就是它,在LDD3这本书中的第三章字符设备驱动,以及第十四章驱动设备模型中多次提到,所以我觉得这个宏应该是内核最经典的宏之一...(ptr, type, member) list.h中提供了list_entry宏来实现对应地址的转换,但最终还是调用了container_of宏,所以container_of宏的伟大之处不言而喻。...* */ #define container_of(ptr, type, member) ({ \ const typeof( ((type *)0)->member...把上面offsetof的宏定义代入container_of宏中,可得到下面定义: #define container_of(ptr, type, member) ({ \
head); pos = pos->next) //获取节点首地址(不是list_head地址,是数据层节点首地址) #define list_entry(ptr, type, member) \ container_of...(ptr, type, member) //container_of在Linux内核中是一个常用的宏,用于从包含在某个 //结构中的指针获得结构本身的指针,通俗地讲就是通过结构体变 //量中某个成员的首地址进而获得整个结构体变量的首地址...#define container_of(ptr, type, member) ({ \ const typeof( ((type *)0)->member ) *__mptr = (...接口,通过结构体变量某个成员的地址,反推结构体首地址,就像 __list_for_each 接口只返回 list_head 地址,所以我们要通过这个成员地址在去获取它本身的结构体首地址,底层实现方法 container_of
CONFIG_HAS_EARLYSUSPEND static void stm_ts_early_suspend(struct early_suspend *h) { struct ftk_ts *ts; ts = container_of...PMSG_SUSPEND); } static void stm_ts_late_resume(struct early_suspend *h) { struct ftk_ts *ts; ts = container_of
= (head); (pos) = (pos)->prev) // 已知一个结构的成员,获取该成员所属结构体地址 #define container_of(ptr, type, menber) \...(type *)((char*)ptr - (char*) &(((type *)0)->menber)) #define list_entry(ptr, type, menber) container_of...(ptr, type, menber) 通过 container_of, 可以取得我们当前正在操作链表所属结构体地址,进而对具体数据进行处理, 利用c语言的一个小技巧, 把结构体投影到地址为0的地方,那么成员的绝对地址就是偏移量
领取专属 10元无门槛券
手把手带您无忧上云