container_of分析

原创分析, 转载请注明出处:http://www.cnblogs.com/langlang/

作者email: dayhappyhappy@163.com


/**
 * 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)); })
container_of作用: 根据一个结构体变量中的一个域成员变量的指针来获取指向整个结构体变量的指针    
    
struct tulip_private {
    const char *product_name;
    struct net_device *next_module;
    struct work_struct media_work;
    struct net_device *dev;
};  
已知:struct work_struct *work;

struct tulip_private *tp = container_of(work, struct tulip_private, media_work);

#define container_of(ptr, type, member) ({            \
    const typeof(((type *)0)->member) * __mptr = (ptr);    \
    (type *)((char *)__mptr - offsetof(type, member)); })

展开第二行begin-------------------------------------------
#define container_of(ptr, type, member) ({            \
    const typeof(((type *)0)->member) * __mptr = (ptr);    \
==>
    
#define container_of(work, struct tulip_private, media_work) ({    
    const typeof(((struct tulip_private *)0)->media_work) * __mptr = (work);
展开第二行end----------------------------------------------    

-----展开第三行begin---------------------------------------
    (struct tulip_private *)((char *)__mptr - offsetof(struct tulip_private, media_work)); })
    #define offsetof(TYPE, MEMBER) ((size_t) &((TYPE *)0)->MEMBER)
    #define offsetof(struct tulip_private, media_work) ((size_t) &((struct tulip_private *)0)->media_work)//计算偏移地址
    {
        (struct tulip_private *)0 是骗编译器说有一个指向类(或结构)s的指针,其地址值0
        &((struct tulip_private *)0)->media_work)   是要取得类struct tulip_private中成员变量media_work的地址. 
    }
    struct tulip_private
    +------------------+ 0xA000
    |   product_name   |
    +------------------+ 0xA004
    |   next_module    |
    +------------------+ 0xA010
    |   media_work     |
    +------------------+ 0xA018
    |   dev            |
    +------------------+
    ((char *)__mptr - offsetof(struct tulip_private, media_work))
    ==>  0xA010 - media_work的偏移地址 =0xA000
    所以: (demo_struct *)((char *)0xA000)指向该结构体的开始地址
    

-----展开第三行end----------------------------------------- 

原文地址:https://www.cnblogs.com/langlang/p/2458079.html