歡迎來到Linux教程網
Linux教程網
Linux教程網
Linux教程網
Linux教程網 >> Linux綜合 >> Linux內核 >> Linux內核源碼中container_of詳解

Linux內核源碼中container_of詳解

日期:2017/2/28 15:57:14   编辑:Linux內核

關於container_of的用法,可參考 http://www.linuxidc.com/Linux/2012-02/53700.htm 。其實就是解決了”如何通過結構中的某個變量的地址獲取結構本身的指針“這樣的問題。container_of實現了根據一個結構體變量中的一個成員變量的指針來獲取指向整個結構體變量的指針的功能。

首先container_of出現在linux/kernel.h中。定義如下:

[cpp]

  1. /**
  2. * container_of - cast a member of a structure out to the containing structure
  3. * @ptr: the pointer to the member.
  4. * @type: the type of the container struct this is embedded in.
  5. * @member: the name of the member within the struct.
  6. *
  7. */
  8. #define container_of(ptr, type, member) ({ \
  9. const typeof( ((type *)0)->member ) *__mptr = (ptr); \
  10. (type *)( (char *)__mptr - offsetof(type,member) );})

typeof( ((type *)0)->member ) *__mptr 就是聲明了一個指向其
我們在看一下offset的定義,在linux/stddef.h中。定義如下:

[cpp]

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

offset顧名思義就是獲得該成員變量基於其包含體地址的偏移量。先分析一下這個宏:
1. ( (TYPE *)0 ) 將零轉型為TYPE類型指針;
2. ((TYPE *)0)->MEMBER 訪問結構中的數據成員;
3. &( ( (TYPE *)0 )->MEMBER )取出數據成員的地址;
4.(size_t)(&(((TYPE*)0)->MEMBER))結果轉換類型。

有人可能感覺很不適應(TYPE *)0這種用法,把一個0轉換成一個結構體指針是什麼意思呢?其實就是聲明了一個指向無物的指針,並告訴編譯器這個指針式指向TYPE類型的,然後成員地址自然為偏移地址,因為成員地址-0還是成員地址。

最後把__mptr 強制類型轉換為char*類型,保證指針相減時是以一個字節為單位進行相減的,保證了程序的正確性。

這樣我們就可以利用container_of來根據一個成員變量的指針來獲取指向整個結構體變量的指針,對於應用層程序而言,這種機制完全沒有必要,但是對於設備驅動程序而言,運用container_of就很有必要了。

Copyright © Linux教程網 All Rights Reserved