linux中的container of

container of解釋

/** 

 * container_of - cast a member of a structure out to the containing structure 

 * @ptr:    the pointer to the member. 

 * @type:   the type of the container struct this is embedded in. 

 * @member: the name of the member within the struct. 

 * 

 */  

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

    const typeof( ((type *)0)->member ) *__mptr = (ptr); \  

(type *)( (char *)__mptr - offsetof(type,member) );})  

  

#define offsetof(TYPE, MEMBER) ((size_t) &((TYPE *)0)->MEMBER)  //這個宏不是在kernel.h文件中定義的。 

 

container_of 宏的作用只有一個:根據結構的成員來獲取包含這個成員的結構實例指針。宏中的參數爲:

ptr:指向成員的指針。

type:需要返回的結構實例類型。

member:成員在結構實例內部的名稱,如果爲數組,需要指定下標。

舉例:

struct test_struct {  

    int num;  

    char ch;  

    float fl;  

};

int main(void)  

{  

    struct test_struct init_test_struct = { 99, 'C', 59.12 };  

  

    char *char_ptr = &init_test_struct.ch;  

  

    struct test_struct *test_struct = container_of(char_ptr, struct test_struct, ch);  

      

    printf(" test_struct->num = %d\n test_struct->ch = %c\n test_struct->fl = %f\n",   

        test_struct->num, test_struct->ch, test_struct->fl);  

      

    return 0;  

}  

例子輸出結果

test_struct->num = 99  

test_struct->ch = C  

test_struct->fl = 59.119999


1、關於就是關於0地址的使用,0地址不是不能被訪問嗎?

typeof( ((type *)0)->member ) *__mptr = (ptr); 

答:

沒錯,0地址當然不能被訪問,這句話的意思是定義了一個跟member數據類型一樣的指針變量__mptr,也就是說如果member的數據類型爲int,那麼typeof( ((type *) NULL)->member ) *__mptr = (ptr); 就等價於int *__mptr = (ptr);,整個typeof( ((type *) NULL)->member ) 語句就是爲了獲得成員member的數據類型。


2、(type *)( (char *)__mptr - offsetof(type,member) ); 不明白爲什麼要把__mptr轉換成char *再相減?

這是指針變量的運算問題,舉個簡單的例子:
int a;
char *p = (char *)&a;
int *q = &a;
這時候,p-1和q-1的值是不是相等呢?
肯定不是,如果&a的值爲0xbffe67b4,那麼p-1爲0xbffe67b3,而q-1則爲0xbffe67b0。
因此,指針變量加減n實際上是加減n個數據類型(p爲char,q爲int)的長度。


發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章