溫馨提示×

Linux內(nèi)核中的container_of淺析

小億
88
2023-12-19 08:19:49
欄目: 編程語言

container_of是Linux內(nèi)核中的一個宏定義,用于根據(jù)結(jié)構(gòu)體中的某個成員變量的地址,找到該結(jié)構(gòu)體的起始地址。

宏的定義如下:

#define container_of(ptr, type, member) ({ \
         const typeof( ((type *)0)->member ) *__mptr = (ptr); \
         (type *)( (char *)__mptr - offsetof(type,member) );})

宏的參數(shù)解釋:

  • ptr:指向某個結(jié)構(gòu)體成員變量的指針。
  • type:結(jié)構(gòu)體的類型。
  • member:結(jié)構(gòu)體中成員變量的名稱。

該宏實際上是通過將指向成員變量的指針轉(zhuǎn)換為結(jié)構(gòu)體指針,來實現(xiàn)找到結(jié)構(gòu)體起始地址的目的。它的實現(xiàn)思路是:

  1. 先定義一個指向成員變量的指針__mptr,類型為成員變量所屬結(jié)構(gòu)體的類型。
  2. 然后通過offsetof宏獲取成員變量在結(jié)構(gòu)體中的偏移量,再通過(char *)__mptr - offsetof(type, member)計算出結(jié)構(gòu)體的起始地址。
  3. 最后將起始地址轉(zhuǎn)換為結(jié)構(gòu)體指針,并返回。

舉個例子來說明,假設(shè)有如下定義的結(jié)構(gòu)體和變量:

struct example_struct {
    int a;
    int b;
    int c;
};

struct example_struct example;
int *ptr = &(example.b);

可以使用container_of宏來找到結(jié)構(gòu)體example的起始地址,示例如下:

struct example_struct *p = container_of(ptr, struct example_struct, b);
printf("%p\n", p);  // 輸出結(jié)構(gòu)體example的起始地址

總結(jié)來說,container_of宏是Linux內(nèi)核中一個十分有用的宏定義,可以根據(jù)結(jié)構(gòu)體中的成員變量的地址快速找到結(jié)構(gòu)體的起始地址,進而方便地進行操作。在內(nèi)核中,它常常被用于實現(xiàn)類似鏈表、隊列等數(shù)據(jù)結(jié)構(gòu)的遍歷和操作。

0