container_of宏
生活随笔
收集整理的這篇文章主要介紹了
container_of宏
小編覺得挺不錯的,現在分享給大家,幫大家做個參考.
1.container_of宏
1> Container_of在Linux內核中是一個常用的宏,用于從包含在某個結構中的指針獲得結構本身的指針,通俗地講就是通過結構體變量中某個成員的首地址進而獲得整個結構體變量的首地址。2>接口:
container_of(ptr, type, member)?
? ptr:表示結構體中member的地址
? type:表示結構體類型
? member:表示結構體中的成員
通過ptr的地址可以返回結構體的首地址
3> container_of的實現:?
#define container_of(ptr, type, member) ({ ? ? ?\ ??
?const typeof( ((type *)0)->member ) *__mptr = (ptr); ? ?\ ?
? (type *)( (char *)__mptr - offsetof(type,member) );}) ?
其實它的語法很簡單,只是一些指針的靈活應用,它分兩步:
第一步,首先定義一個臨時的數據類型(通過typeof( ((type *)0)->member )獲得)與ptr相同的指針變量__mptr,然后用它來保存ptr的值。
說明:typeof是GNU C對標準C的擴展,它的作用是根據變量獲取變量的類型《typeof關鍵字在linux 內核中很常見》
第二步,用(char *)__mptr減去member在結構體中的偏移量,得到的值就是整個結構體變量的首地址(整個宏的返回值就是這個首地址)。
關于offsetof的用法可參見offsetof宏的使用。
2. 舉例來說明container_of的使用
1>正確示例:
#include <stdio.h>#define offsetof(TYPE, MEMBER) ((size_t) &((TYPE *)0)->MEMBER)
#define ?container_of(ptr, type, member) ({ ? ? ? ? ? ? ? ? ? ? ?\
? ? ? ? ? ? ? ? ? ? ? const typeof( ((type *)0)->member ) *__mptr = (ptr); ? ?\
? ? ? ? ? ? ? ? ? ? ? ?(type *)( (char *)__mptr - offsetof(type,member) );})
struct test_struct {
? ? ? ? ? ?int num;
? ? ? ? ? char ch;
? ? ? ? ? float f1;
? };
?int main(void)
? {
? ? ? ? ? struct test_struct *test_struct;
? ? ? ? ? struct test_struct init_struct ={12,'a',12.3};
? ? ? ? ? char *ptr_ch = &init_struct.ch;
? ? ? ? ? test_struct = container_of(ptr_ch,struct test_struct,ch);
? ? ? ? ? printf("test_struct->num =%d\n",test_struct->num);
? ? ? ? ? printf("test_struct->ch =%c\n",test_struct->ch);
? ? ? ? ? printf("test_struct->ch =%f\n",test_struct->f1);
? ? ? ? ? return 0;
? }
執行結果:
jibo@jibo-VirtualBox:~/cv_work/work/list/container_of $ ./main
test_struct->num =12
test_struct->ch =a
test_struct->ch =12.300000
2>錯誤示例:
? #include <stdio.h>?? #define offsetof(TYPE, MEMBER) ((size_t) &((TYPE *)0)->MEMBER)
? #define ?container_of(ptr, type, member) ({ ? ? ? ? ? ? ? ? ? ? ?\
? ? ? ? ? ? ? ? ? ? ? ? ? ?const typeof( ((type *)0)->member ) *__mptr = (ptr); ? ?\
? ? ? ? ? ? ? ? ? ? ? ? ? (type *)( (char *)__mptr - offsetof(type,member) );})?
? ?struct test_struct {
? ? ? ? ? ?int num;
? ? ? ? ? char ch;
? ? ? ? ? float f1;
? };?
? int main(void)
? {
? ? ? ? ? struct test_struct *test_struct;
? ? ? ? ? char real_ch = 'A';
? ? ? ? ? char *ptr_ch = &real_ch;
? ? ? ? ? test_struct = container_of(ptr_ch,struct test_struct,ch);
? ? ? ? ? printf("test_struct->num =%d\n",test_struct->num);
? ? ? ? ? printf("test_struct->ch =%c\n",test_struct->ch);
? ? ? ? ? printf("test_struct->ch =%f\n",test_struct->f1);
? ? ? ? ? return 0;
? }
執行結果為:
jibo@jibo-VirtualBox:~/cv_work/work/list/container_of1 $ ./main
test_struct->num =0
test_struct->ch =A
test_struct->ch =0.000000
注意,由于這里并沒有使用一個具體的結構體變量,所以成員num和f1的值是不確定的。
總結
以上是生活随笔為你收集整理的container_of宏的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: Python进阶全系列
- 下一篇: 设计(二) | PS功能快捷键(全)