Linux内核宏Container_Of的详细解释

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个参数,分别是:

  1. ptr:结构体成员的指针;
  2. type:结构体的类型;
  3. 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结构体和两个指向该结构体的指针pq。其中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结构体和两个指针pheadnode结构体包含一个整数成员val和一个指向下一个节点的list_head结构体指针listhead指向链表的头节点。

使用list_for_each宏遍历链表的每个元素,pos指向当前元素的list_head结构体。使用Container_Of宏获取包含pos结构体的node结构体指针,最后输出该元素的val成员。

总体来说,Container_Of是一个非常有用的宏,在Linux内核源码中被广泛使用。通过理解它的实现和使用方法,我们可以更好地理解Linux内核的数据结构和算法。

本站文章如无特殊说明,均为本站原创,如若转载,请注明出处:Linux内核宏Container_Of的详细解释 - Python技术站

(0)
上一篇 2023年6月27日
下一篇 2023年6月27日

相关文章

  • 说说前端开发中的seo

    说说前端开发中的 SEO 什么是 SEO SEO(Search Engine Optimization),搜索引擎优化。它是指通过改变网站内容以及在页面上增加关键字等优化措施,以增加自然搜索引擎(例如谷歌、百度)对网站的搜索排名,从而提高网站流量,最终目的是提升网站在自然搜索结果中的可见度。 前端开发在 SEO 中的作用 前端开发中的 HTML、CSS、Ja…

    其他 2023年3月28日
    00
  • xml文件怎么打开

    XML是一种标准的数据交换格式,可以用于表示各种类型的数据。本文将详细讲解如何打开XML文件,包括在Windows、Mac和Linux操作系统中使用的方法。 在Windows中打开XML文件 在Windows中打开XML文件,你可以使用以下两种方法: 方法1:使用文本编辑器 右键单击XML文件并选择“编辑”或“打开方式”选项; 选择“记事本”、“Notepa…

    其他 2023年4月16日
    00
  • C++中类的默认成员函数详解

    下面是关于“C++中类的默认成员函数详解”的完整攻略。 什么是默认成员函数? 在C++中,每个类默认会有一些成员函数。这些函数被称为默认成员函数。默认构造函数、默认析构函数和默认拷贝构造函数是C++中最常见的默认成员函数。 默认构造函数 默认构造函数是一个没有参数的构造函数。它被用来实例化一个对象,当用户没有指定初始值时,就会调用默认构造函数。如果用户没有定…

    other 2023年6月26日
    00
  • Spring中xml配置文件的基础使用方式详解

    下面就来详细讲解Spring框架中xml配置文件的基础使用方式。 一、Spring中xml配置文件的作用 Spring框架采用xml配置文件的方式,可以定义bean(Java对象)以及它们之间的关系,通过配置的方式告诉Spring容器应该实例化哪些bean,以及它们之间如何协作。因此,xml配置文件扮演着Spring应用程序的重要角色。 二、Spring中x…

    other 2023年6月25日
    00
  • Flash cs6怎么创建数组元素?

    下面是详细的攻略,包含Flash CS6创建数组元素的过程以及示例说明。 创建Flash CS6数组元素的攻略 第一步:创建一个数组变量 在Flash CS6中,创建一个数组变量需要使用Array类。可以通过var关键字和数组字面量语法,来直接声明和创建一个空数组变量。例如: var myArray: Array = []; 以上代码创建了一个空的名为myA…

    other 2023年6月26日
    00
  • Python3标准库glob文件名模式匹配的问题

    当我们需要对文件名进行批量处理时,常常使用文件名匹配模式,glob是Python标准库提供的文件名匹配模块,可以通过指定特定的文件名模式来返回符合条件的文件列表。 glob的使用 glob主要包含了三个函数:glob、iglob以及glob2。 glob函数:列出符合特定规则的文件或目录,返回一个列表。 iglob函数:功能与glob函数类似,但是返回的是一…

    other 2023年6月26日
    00
  • cygwin下gcc编译环境安装

    cygwin下gcc编译环境安装 对于喜欢使用Windows平台作为主要开发环境的程序员,cygwin是一个十分常用的工具。这个工具可以提供一些常见的UNIX/Linux命令和工具,同时提供一个bash shell环境,方便在Windows上使用一些基本的UNIX/Linux工具。当然,对于使用C/C++语言的开发者,cygwin也提供了GCC这个编译器。 …

    其他 2023年3月28日
    00
  • IOS 使用Block二次封装AFNetworking 3.0详解

    IOS 使用Block二次封装AFNetworking 3.0详解 1. 前言 AFNetworking 是 iOS 开发中常用的网络请求库,其基于 NSURLConnection 和 NSURLSession,提供了更加简单方便的接口,使得开发者可以方便地进行网络请求。 但是,AFNetworking 中的回调方式为传统的代理方法,不够便捷。为此,我们可以…

    other 2023年6月25日
    00
合作推广
合作推广
分享本页
返回顶部