揭開linux內核中container_of的神秘面紗
時間(jian):2016-12-22作者:華清遠見
在linux 內核中有一個大(da)名鼎(ding)鼎(ding)的(de)宏container_of(),這(zhe)個宏是(shi)用來(lai)干嘛的(de)呢(ni)?我們先來(lai)看(kan)看(kan)它(ta)在內核中是(shi)怎樣(yang)定義的(de)。
呵(he)呵(he),乍一看不知道(dao)是什么東東。 我們(men)先來分析一(yi)下container_of(ptr,type,member),這里面有ptr,type,member分別代表指(zhi)針(zhen)、類型、成員。看一(yi)個例子:
Struct test 現在呢如果我想通過temp.j的地(di)址(zhi)(zhi)找到(dao)temp的首地(di)址(zhi)(zhi)就可以(yi)使用container_of(&temp.j,struct test,j); 現(xian)在我們知(zhi)道container_of()的(de)作用(yong)就是通(tong)過一個結構變量中一個成(cheng)員的(de)地(di)址(zhi)找到這個結構體變量的(de)首地(di)址(zhi)。 下面來看(kan)看(kan)比(bi)較復(fu)雜的內容:
我們用(yong)上(shang)面(mian)的struct test張展一下(xia) Const typeof(((struct test *)0)->j) * __mptr = (&temp.j); 其中(zhong),typeof是(shi)GNU C對標準C的(de)擴(kuo)展,它的(de)作用是(shi)根據變(bian)量(liang)(liang)獲(huo)取變(bian)量(liang)(liang)的(de)類型(xing)。因此,上述代碼的(de)作用是(shi)首先使用typeof獲(huo)取結(jie)構體(ti)成員j的(de)類型(xing)為int,然后(hou)頂一個int指針類型(xing)的(de)臨(lin)時變(bian)量(liang)(liang)__mptr,并將(jiang)結(jie)構體(ti)變(bian)量(liang)(liang)中(zhong)的(de)成員的(de)地址(zhi)賦(fu)給臨(lin)時變(bian)量(liang)(liang)__mptr。 (struct test *)((char *)__mptr - offsetof(struct test,j)); 接著我(wo)們來看一下offsetof(struct test,j),他在內核中如下定義
展開(kai)(size_t)&((struct test *)0)->j,這是什么東(dong)東(dong)? 一開始(shi)也不(bu)明白,這(zhe)里(li)要感謝曹(cao)老(lao)師老(lao)師的熱(re)心幫(bang)助,一語(yu)驚醒夢中(zhong)人,呵(he)呵(he),可以是(shi)這(zhe)樣理解。
其(qi)中size_t是整型,那么我們可以知道(dao)終(zhong)的結果是一(yi)個整形值(zhi),也(ye)就是j相對于0地(di)址的偏(pian)移量。也(ye)許現在你會問,整出這么個玩意干嘛,下面(mian)看(kan)個列子:
程序運行(xing)結果:
發現沒有如果把(ba)第(di)二個值 減去后一(yi)(yi)個值,就能(neng)得到第(di)一(yi)(yi)個值。 在回(hui)首一下它(ta): (struct test *)((char *)__mptr - offsetof(struct test,j)); 是(shi)不是(shi)可(ke)以獲得結構體變量temp的首地(di)址呀,是(shi)不是(shi)太精妙了呀,linux內核中隨隨便便一個宏就(jiu)有如此精妙,呵(he)呵(he),想想對(dui)linux了解非常多的牛人,還(huan)有很(hen)長一段(duan)路。
相關資訊
發表評論
|