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

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

    typedef unsigned int    __kernel_size_t;
    typedef __kernel_size_t        size_t;
    #define offsetof(TYPE, MEMBER) ((size_t) &((TYPE *)0)->MEMBER)
    
    /**
     * container_of - cast a member of a structure out to the containing structure
     * @ptr:        the pointer to the member.
     * @type:       the type of the container struct this is embedded in.
     * @member:     the name of the member within the struct.
     *
     */
    #define container_of(ptr, type, member) ({                      
        const typeof( ((type *)0)->member ) *__mptr = (ptr);    
        (type *)( (char *)__mptr - offsetof(type,member) );})
        
    struct person
    {
        char name[10];
        int age;
        int num;
    } ocjPerson;
    
    int main(void)
    {
        struct person* p =  container_of(&ocjPerson.age, struct person, age);
        
        printf("the value of p = %x
    ", p);
        printf("the value of &ocjPerson = %x
    ", &ocjPerson);
        
        return 0;
    }
    
    /*
    打印结果:
      the value of p == the value of &ocjPerson

    分析:
    container_of(&ocjPerson.age, struct person, age); ({ const typeof( ((struct person *)0)->age ) *__mptr = (&ocjPerson.age); (struct person *)( (char *)__mptr - ((size_t) &((struct person *)0)->age) );}) A. typeof是GNU C对标准C的扩展,它的作用是根据变量获取变量的类型 B.#define offsetof(TYPE, MEMBER) ((size_t) &((TYPE *)0)->MEMBER) 分析一下这个offsetof宏的运行机理: 一共4步 1. ( (TYPE *)0 ) 将零转型为TYPE类型指针; 2. ((TYPE *)0)->MEMBER 访问结构中的数据成员; 3. &( ( (TYPE *)0 )->MEMBER )取出数据成员的地址; 4.(size_t)(&(((TYPE*)0)->MEMBER))结果转换类型。巧妙之处在于将0转换成(TYPE*),结构以内存空间首地址0作为起始地址,则成员地址自然为偏移地址; */
  • 相关阅读:
    面试遇到的问题汇总
    linux系统的安装和配置
    apache重写URL时,排除静态资源
    WordPress限制游客查看文章
    Mysql主从复制读写分离
    Postgres主从
    django-rest-framework-simplejwt
    JavaWeb项目部署到Linux服务器
    Centos8.2云服务器环境安装Tomcat8.5
    java的pdf转jpg
  • 原文地址:https://www.cnblogs.com/mylinux/p/5497391.html
Copyright © 2011-2022 走看看