container of巨集定義

2021-06-22 15:53:58 字數 2955 閱讀 9314

1> container_of在linux核心中是乙個常用的巨集,用於從包含在某個結構中的指標獲得結構本身的指標,通俗地講就是通過結構體變數中某個成員的首位址進而獲得整個結構體變數的首位址。

2>介面:

container_of(ptr, type, member) 

ptr:表示結構體中member的位址

type:表示結構體型別

member:表示結構體中的成員

通過ptr的位址可以返回結構體的首位址

3> container_of的實現: 

#define container_of(ptr, type, member) ()  

其實它的語法很簡單,只是一些指標的靈活應用,它分兩步:

第一步,首先定義乙個臨時的資料型別(通過typeof( ((type *)0)->member )獲得)與ptr相同的指標變數__mptr,然後用它來儲存ptr的值。

說明:typeof是gnu c對標準c的擴充套件,它的作用是根據變數獲取變數的型別《typeof關鍵字在linux 核心中很常見》

第二步,用(char *)__mptr減去member在結構體中的偏移量,得到的值就是整個結構體變數的首位址(整個巨集的返回值就是這個首位址)。

關於offsetof的用法可參見offsetof巨集的使用。

#include

#define offsetof(type, member) ((size_t) &((type *)0)->member)

#define  container_of(ptr, type, member) ()

struct test_struct ;

int main(void)

;char *ptr_ch = &init_struct.ch;

test_struct = container_of(ptr_ch,struct test_struct,ch);

printf("test_struct->num =%d\n",test_struct->num);

printf("test_struct->ch =%c\n",test_struct->ch);

printf("test_struct->ch =%f\n",test_struct->f1);

return 0;

}執行結果:

jibo@jibo-virtualbox:~/cv_work/work/list/container_of $ ./main

test_struct->num =12

test_struct->ch =a

test_struct->ch =12.300000

#include

#define offsetof(type, member) ((size_t) &((type *)0)->member)

#define  container_of(ptr, type, member) () 

struct test_struct ; 

int main(void)

執行結果為:

jibo@jibo-virtualbox:~/cv_work/work/list/container_of1 $ ./main

test_struct->num =0

test_struct->ch =a

test_struct->ch =0.000000

注意,由於這裡並沒有使用乙個具體的結構體變數,所以成員num和f1的值是不確定的。

#define offsetof(type, member) ((size_t) &((type*)0)->member)

對這個巨集的講解我們大致可以分為以下4步進行講解:

1>( (type *)0 )  0位址強制 "轉換" 為 type結構型別的指標;

2>((type *)0)->member   訪問type結構中的member資料成員;

3>&( ( (type *)0 )->member)取出type結構中的資料成員member的位址;

4>(size_t)(&(((type*)0)->member))結果轉換為size_t型別。

巨集offsetof的巧妙之處在於將0位址強制轉換為 type結構型別的指標,type結構以記憶體空間首位址0作為起始位址,則成員位址自然為偏移位址。可能有的讀者會想是不是非要用0呢?當然不是,我們僅僅是為了計算的簡便。也可以使用是他的值,只是算出來的結果還要再減去該數值才是偏移位址。來看看如下的**:

#include

#defineoffsetof(type, member) ((size_t) &((type *)4)->member)

struct test_struct ;

int main(void)

執行結果為:

jibo@jibo-virtualbox:~/cv_work/work/list/offset $ ./main

offsetof (struct test_struct,num) =0

offsetof (struct test_struct,ch) =4

offsetof (struct test_struct,f1) =8

為了讓大家加深印象,我們在**中沒有使用0,而是使用的4,所以在最終計算出的結果部分減去了乙個4才是偏移位址,當然實際使用中我們都是用的是0。

#include

#defineoffsetof(type, member) ((size_t) &((type *)0)->member)

struct test_struct ;

int main(void)

執行結果為:

jibo@jibo-virtualbox:~/cv_work/work/list/offset $ ./main

offsetof (struct test_struct,num) =0

offsetof (struct test_struct,ch) =4

offsetof (struct test_struct,f1) =8

核心 巨集定義 container of

container of 1.1 container of介紹 定義 container of在linux核心的include linux kernel.h中定義。define container of ptr,type,member 說明 根據 結構體 type 變數 中的 域成員變數 membe...

container of 巧妙的巨集定義

include linux kernel.h define container of ptr,type,member include linux stddef.h define offsetof type,member size t tpye 0 member container of 中,第乙個引...

Linux 巨集定義container of詳解

在寫linux驅動的過程中經常是乙個結構體套一層結構體,而在某些函式中傳入的引數是子結構體指標,但是我們又需要獲取的其外層結構體的資料,linux為我們提供了container of巨集定義來為我們解決這個問題。container of巨集定義就是用來通過內層結構體的指標獲取外層結構體指標,巨集定義...