container_of宏的詳細介紹與解答

首先,今天看到代碼,接觸到這個宏定義,所以有意去研究了一下:

struct hid_device *hdev = container_of(dev, struct hid_device, dev);

以上面例子來說這個宏的作用爲:根據一個結構體變量中的一個域成員變量的指針來獲取指向整個結構體變量的指針

/** 
* container_of - cast a member of a structure out to the containingstructure 
* @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) );})

以上參數英文的,相信能夠寫代碼的童鞋都能看得懂的吧。下面針對這個宏我做下詳細的介紹:

1.宏的最外圍是   ({})    ,這個結構的作用舉個例子:

 

intx=({7;1;})+2;

printf("%d\n",x);

輸出的值爲3,意思就是這個結構會找出最後一個定義的值來做運算,說的夠直白吧?

2.宏的內部有一個typeof,這個作用就是爲了申明一個類型,((type *)0)將零轉化爲type(這裏的type是一個結構體類型)的指針類型,指向我們的結構體成員member,就是以零地址開始開始指向member。

3.那麼我想問一下大家&((type *)0)->member是否可以說是member在整個結構體中的偏移量?ok,那麼我就就僅僅認爲((type *)0)->member僅僅只一個member類型的數據,typeof( ((type *)0)->member ) *__mptr就是說定義一個member數據類型的指針變量__mptr,等於指向member的指針變量。

4.(type *)( (char *)__mptr - offsetof(type,member) ),咋一看,offsetof不知道什麼意思,ok

 

#define offsetof(TYPE, MEMBER) ((size_t) &((TYPE *)0)->MEMBER)

什麼意思呢?這不就是我們剛纔分析的嗎?返回member的偏移量嘛,不解釋!看不懂的自己把第三點再看一遍,然後告訴我你懂了!

 

5.那麼前面的 (type *)( (char *)__mptr - offsetof(type,member) )整體看上去一些小夥伴還是看着喫力,有木有?ok,(char *)__mptr將__mptr轉換爲字符型指針,原來指向member的,減去它的偏移量,那麼就得到它原本所在結構的首地址。那麼回到

struct hid_device *hdev = container_of(dev, struct hid_device, dev);

該hid設備不就是爲了得到hid_device的首地址 ({}) 定義的最後一個就是其返回的值,那麼就是首地址。

 

 

 

 

 

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