揭開linux內(nèi)核中container_of的神秘面紗
時(shí)間:2016-12-22作者:華清遠(yuǎn)見
在linux 內(nèi)核中有一個(gè)大名鼎鼎的宏container_of(),這個(gè)宏是用來(lái)干嘛的呢?我們先來(lái)看看它在內(nèi)核中是怎樣定義的。
呵呵,乍一看不知道是什么東東。 我們先來(lái)分析一下container_of(ptr,type,member),這里面有ptr,type,member分別代表指針、類型、成員。看一個(gè)例子:
Struct test 現(xiàn)在呢如果我想通過(guò)temp.j的地址找到temp的首地址就可以使用container_of(&temp.j,struct test,j); 現(xiàn)在我們知道container_of()的作用就是通過(guò)一個(gè)結(jié)構(gòu)變量中一個(gè)成員的地址找到這個(gè)結(jié)構(gòu)體變量的首地址。 下面來(lái)看看比較復(fù)雜的內(nèi)容:
我們用上面的struct test張展一下 Const typeof(((struct test *)0)->j) * __mptr = (&temp.j); 其中,typeof是GNU C對(duì)標(biāo)準(zhǔn)C的擴(kuò)展,它的作用是根據(jù)變量獲取變量的類型。因此,上述代碼的作用是首先使用typeof獲取結(jié)構(gòu)體成員j的類型為int,然后頂一個(gè)int指針類型的臨時(shí)變量__mptr,并將結(jié)構(gòu)體變量中的成員的地址賦給臨時(shí)變量__mptr。 (struct test *)((char *)__mptr - offsetof(struct test,j)); 接著我們來(lái)看一下offsetof(struct test,j),他在內(nèi)核中如下定義
展開(size_t)&((struct test *)0)->j,這是什么東東? 一開始也不明白,這里要感謝曹老師老師的熱心幫助,一語(yǔ)驚醒夢(mèng)中人,呵呵,可以是這樣理解。
其中size_t是整型,那么我們可以知道終的結(jié)果是一個(gè)整形值,也就是j相對(duì)于0地址的偏移量。也許現(xiàn)在你會(huì)問(wèn),整出這么個(gè)玩意干嘛,下面看個(gè)列子:
程序運(yùn)行結(jié)果:
發(fā)現(xiàn)沒有如果把第二個(gè)值 減去后一個(gè)值,就能得到第一個(gè)值。 在回首一下它: (struct test *)((char *)__mptr - offsetof(struct test,j)); 是不是可以獲得結(jié)構(gòu)體變量temp的首地址呀,是不是太精妙了呀,linux內(nèi)核中隨隨便便一個(gè)宏就有如此精妙,呵呵,想想對(duì)linux了解非常多的牛人,還有很長(zhǎng)一段路。
相關(guān)資訊
發(fā)表評(píng)論
|