zoukankan      html  css  js  c++  java
  • linux内核宏container_of

      首先来个简单版本

    1 /* given a pointer @ptr to the field @member embedded into type (usually
    2  * struct) @type, return pointer to the embedding instance of @type. */
    3 #define container_of(ptr, type, member) 
    4     ((type *)((char *)(ptr)-(char *)(&((type *)0)->member)))

      作用:主要用于结构体,给定一个指针ptr指向一个结构体type的实例的成员member,返回此结构体实例的首地址,也就是这个结构体实例的指针,啰嗦一堆,还不如一个实例:

     1 typedef struct ABC{
     2     char a;
     3     char b;
     4     int c;
     5 }ABC;
     6 
     7 int main(int argc, const char *argv[])
     8 {
     9     ABC ins;
    10 
    11     printf("%p
    ", container_of(&ins.c, ABC, c));
    12     printf("%p
    ", &ins);
    13     return 0;
    14 }

      打印出来的值应该是相等的,都是结构体ins的首地址。我们将宏展开:

     container_of(&ins.c, ABC, c);
    //展开后
    ((ABC *)((char *)(&ins.c)-(char *)(&((ABC *)0)->c)));

      在减号的2边分别是2个部分,前面: (char *)(&ins.c),也就是指向ins的成员c的指针,后面:(char *)( &(((ABC *)0)->c))就是成员c相对于结构体ABC指针的偏移,比如在本例中:

    成员c的指针(&ins.c)减去成员c的偏移(offset)那么得到的就是结构体ins首地址。如果我只知道某个结构体成员的指针值,那么通过container_of宏就可以得到结构体指针,那么就可以随意访问它的任意一个成员。

    升级版:

    1 #define offsetof(typ,memb) ((long)(long_ptr_t)((char *)&(((typ *)0)->memb)))
    2 #define container_of(ptr, type, member) ({            
    3     const typeof( ((type *)0)->member ) *__mptr = (ptr);    
    4     (type *)( (char *)__mptr - offsetof(type,member) );})

    升级版有何改进呢?我就我知道的总结下:

    1.const修饰,确保传入的ptr指向不被修改。2.使用了一个中间变量,定义一个成员member类型的变量指针__mptr,然后将ptr赋值给它。为何要这样?就是为了以防万一,如果你搞错了传的指针不是指向成员member的,那么编译器至少会有个警告。

    3.offset宏使用(long)(long_ptr_t)2个数据类型作强转我没看太懂,(long long )64位?一个成员的偏移有可能超过32位?倒是__mptr这个地址值可能超过32位(寻址超过4G)。不解。

    参考:

      http://broken.build/2012/11/10/magical-container_of-macro/

      linux 3.13.0内核。

  • 相关阅读:
    http url转义字符,特殊字符
    No bean named 'cxf' is defined
    c语言中结构体指针
    Android fragment (二)
    文件I/O之C标准库函数和系统库函数差别
    计算机组成原理——主存与cache的映射关系
    openstack 用nova API 指定 compute node 创建 instance
    SQL存在一个表而不在还有一个表中的数据
    hdu 2602
    小金登陆游戏
  • 原文地址:https://www.cnblogs.com/thammer/p/4491368.html
Copyright © 2011-2022 走看看