zoukankan      html  css  js  c++  java
  • container_of

     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) );})

    它的作用显而易见,那就是根据一个结构体变量中的一个域成员变量的指针来获取指向整个结构体变量的指针

    1 #undef offsetof
    2 #ifdef __compiler_offsetof
    3 #define offsetof(TYPE,MEMBER) __compiler_offsetof(TYPE,MEMBER)
    4 #else
    5 #define offsetof(TYPE, MEMBER) ((size_t) &((TYPE *)0)->MEMBER)
    6 #endif

    需要注意的是,要使用container_of,则type中成员member不能为指针。(若其为指针,则ptr为指针的指针,为程序带来复杂性)。

    此处错误应删除(指针成员与非指针成员同等处理即可)。例程中如下代码即可验证,但是若为指针时container_of()的第一参数ptr存储的是member成员的地址(即指针的地址),而非指针值。

    #if 1
        stu2.scc="ABCD";
        str = &(stu2.scc);
        pstu1 = container_of(str, stu, scc);
        printf("The score is %s
    ", pstu1->scc);
    #endif

    详细示例参考“设备结构体设计思考”。

    #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) );})
    
    typedef struct {
        char score;
    } core_grade;
    
    typedef struct {
        int no; 
        int age;
        core_grade grade;
        char sc; 
      char *scc; } stu,
    *pstu; int main(int argc, char *argv[]) { stu stu1, stu2, *pstu1=NULL; char *pch = NULL;
      void *str = NULL; // save addr
    #if 0 stu1.grade.score='A'; pch = &(stu1.grade.score); pstu1 = container_of(pch, stu, score); printf("The score is %c ", (pstu1->grade).score); #endif #if 1 stu1.sc='A'; pch = &(stu1.sc); pstu1 = container_of(pch, stu, sc); printf("The score is %c ", pstu1->sc); #endif

     #if 1
      stu2.scc="ABCD";
      str = &(stu2.scc);
      pstu1 = container_of(str, stu, scc);
      printf("The score is %s ", pstu1->scc);
     #endif

        return 0;
    }

    上述代码同时验证了,container_of不能穿透结构体(#if 0...#endif)。

    上述结论错误,container_of()的第二个参数type和第三个参数member必须是直接的包含关系时才可以;若是间接包含,则第三个参数必须拓展到直接包含的成员引用才可以。

    上述code中container_of报错:

    pstu1 = container_of(pch, stu, score);
    structinc.c:6:30: error: ‘stu {aka struct <anonymous>}’ has no member named ‘score’
         const typeof( ((type *)0)->member ) *__mptr = (ptr);    

    但改为如下code则编译成功:

    pstu1 = container_of(pch, stu, grade.score);

    参考:设备接口体应用container_of的思考

  • 相关阅读:
    浏览器输入一个url到整个页面显示出来经历了哪些过程?
    ajax
    为什么JS是单线程?JS中的Event Loop(事件循环)?JS如何实现异步?setimeout?
    jQuery中ready方法的实现
    this+call、apply、bind的区别与使用
    内存泄漏、垃圾回收机制、哪些情况会导致内存泄漏
    浏览器同源策略和跨域方法
    node.js
    JS原型、原型链、构造函数、实例与继承
    JS常用操作节点的方法
  • 原文地址:https://www.cnblogs.com/embedded-linux/p/5496462.html
Copyright © 2011-2022 走看看