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)的長度。