Linux內核:container_of宏分析

版權聲明:本文爲博主原創文章,未經博主允許不得轉載。 https://blog.csdn.net/JansonZhe/article/details/47343637

我們在編寫驅動程序的時候,會經常在open函數中用到container_of宏,那麼這個在linux內核中這個宏的主要作用是什麼呢?
所在linux目錄
tool\perf\util\include\linux\Kernel.h

主要功能
首先簡述一下container_of的主要功能:對於給定結構體成員的地址,從而找到該結構體的首地址。換句話說就是,如果已經知道了一個結構體成員的地址,那麼通過container_of函數就可以知道該結構體的入口地址,也就是首地址啦。

參數分析
首先看一下container_of的表達式:container_of(ptr,type,member),從表達式可以看出container_of宏一共需要三個參數,下面分別介紹:

ptr: 結構體成員的地址或者指針
type: 結構體類型
member: 成員名稱

通過這三個參數,就可以返回該結構體的首地址了。

例子分析
結構體

struct test
{
    int i;
    int j;
    char k;
};
Struct test temp;

現在呢,如果我想通過temp.j的地址找到結構體temp的首地址,就可以使用我們的container_of宏。

container_of(&temp.j, struct test, j);

源代碼分析
首先來看一下我們的源代碼:

#define container_of(ptr, type, member) ({          \
    const typeof(((type *)0)->member) * __mptr = (ptr); \
    (type *)((char *)__mptr - offsetof(type, member)); })
#endif

第一段代碼是:

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

這裏linux內核使用了一個typeof函數,typeof是GNU對標準C的擴展,它的作用是根據變量獲取變量類型,而(type )0則表示type結構體指針0的成員變量member,因此typeof(((type )0)->member)則表示member的變量類型,從而_mptr就表示爲member類型的指針變量,同時指向ptr指針,也就是說將ptr指向的地址賦給了_member指針變量。

我們再來看第二句代碼:

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

這句代碼相對比較複雜,我們詳細分析下,首先由左邊的( type * ),我們知道這條代碼的返回值類型爲type指針類型。而對於((char *)__mptr - offsetof(type, member)),我們要了解offsetof的作用。
offsetof的表達式爲offsetof(TYPE, MEMBER),表示爲type與member的相對地址差。因此我們便知道了((char *)__mptr - offsetof(type, member))表示_mptr地址減去type與member的相對地址差,從而得到結構體type的首地址。

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