Linux内核宏Container_Of的详细解释
Container_Of是一个在Linux内核源码中广泛使用的宏,它的作用是根据某个结构体成员的指针推导出该结构体的指针。该宏的定义如下:
#define container_of(ptr, type, member) \
({ \
const typeof( ((type *)0)->member ) *__mptr = (ptr); \
(type *)( (char *)__mptr - offsetof(type, member) ); \
})
宏定义解析
该宏有3个参数,分别是:
ptr
:结构体成员的指针;type
:结构体的类型;member
:结构体成员的名称。
首先,宏定义使用了GCC的特性——语句表达式(({ ... })
),这使得可以在宏定义中使用代码块,从而使宏定义更加灵活。
接下来的第一行定义了一个指针__mptr
,类型是指向member
成员的指针,__mptr
的值是ptr
。因为typeof
是GCC的一个扩展,所以可以使用__typeof__
作为它的替代品。
最后一行使用了C语言的指针算术运算,将__mptr
强制转换成了结构体type
的指针。其中offsetof
是C语言库函数中的一个宏,用于获取结构体成员相对于结构体首地址的偏移量。
示例说明一
下面是一个例子,展示如何使用Container_Of
来获取某个结构体的指针:
struct my_struct {
int a;
int b;
int c;
};
struct my_struct *p, *q;
/* p指向a成员,使用Container_Of宏获取my_struct结构体指针 */
p = (struct my_struct *)(&(q->a)); // q为我们要找的结构体指针
q = container_of(p, struct my_struct, a);
在上述示例中,我们首先声明了一个my_struct
结构体和两个指向该结构体的指针p
和q
。其中p
指向my_struct
结构体中的a
成员,使用Container_Of
宏获取my_struct
结构体指针,最后将指针赋值给了q
。
示例说明二
下面是另一个例子,展示如何遍历链表。在链表中,每个节点都包含一个指向下一个节点的指针:
struct node {
int val;
struct list_head list;
};
struct node *p;
struct list_head *pos, *head;
/* 遍历链表的每个元素 */
list_for_each(pos, head) {
/* pos指向当前元素的list_head结构体,
* 使用Container_Of获取包含该结构体的node结构体指针*/
p = container_of(pos, struct node, list);
printf("%d\n", p->val);
}
在上述示例中,我们首先声明了一个node
结构体和两个指针p
和head
。node
结构体包含一个整数成员val
和一个指向下一个节点的list_head
结构体指针list
。head
指向链表的头节点。
使用list_for_each
宏遍历链表的每个元素,pos
指向当前元素的list_head
结构体。使用Container_Of
宏获取包含pos
结构体的node
结构体指针,最后输出该元素的val
成员。
总体来说,Container_Of
是一个非常有用的宏,在Linux内核源码中被广泛使用。通过理解它的实现和使用方法,我们可以更好地理解Linux内核的数据结构和算法。
本站文章如无特殊说明,均为本站原创,如若转载,请注明出处:Linux内核宏Container_Of的详细解释 - Python技术站