container_of分析笔记

//分析container_of
#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) );} )
        
 /*
 container_of(p, struct adv7170, sd)展开就是: 
{
        const typeof( ((struct adv7170 *)0)->sd ) *__mptr = (p);         //这句是定义,定义一个变量__mptr(不在函数一开始定义时就得另起一对花括号)
        (struct adv7170 *) (   (char *)__mptr - ( (size_t) &((struct adv7170 *)0)->sd )   );
}
 
  重点分析: const typeof( ((struct adv7170 *)0)->sd ) *__mptr = (p); 
 这句其实等价: const struct v4l2_subdev *__mptr = p; 
说明: typeof( ((struct adv7170 *)0)->sd )这货其实就是获取sd这个变量的类型,它的类型当然是struct v4l2_device       
 
  总结: 已知p的位置,求它外层结构体struct adv7170中的首地址?
 解决问题的思路就是将p的地址减去p在 struct adv7170结构体中的偏移量就得出
 struct adv7170的首地址了;
 */       
        
struct adv7170 {
        int test;
        struct v4l2_subdev sd;                  // struct adv7170 里包含struct v4l2_subdev ,现在想知道struct adv7170的位置
        unsigned char reg[128];
        v4l2_std_id norm;
        int input;
};
struct v4l2_subdev {
        struct list_head list;
        struct module *owner;
        struct v4l2_device *v4l2_dev;
        const struct v4l2_subdev_ops *ops;
        /* name must be unique */
        char name[V4L2_SUBDEV_NAME_SIZE];
        /* can be used to group similar subdevs, value is driver-specific */
        u32 grp_id;
        /* pointer to private data */
        void *priv;
};


static inline struct adv7170 *to_adv7170(struct v4l2_subdev *p)
{
        return container_of(p, struct adv7170, sd);
}

static int adv7170_write_block(struct v4l2_subdev *sd, const u8 *data, unsigned int len)
{
        struct i2c_client *client = v4l2_get_subdevdata(p);
        struct adv7170 *encoder = to_adv7170(p);       //在这里调用的,想利用sd找到母体 ???????????????????????????
        ... ...
}

static int adv7170_s_std_output(struct v4l2_subdev *p, v4l2_std_id std)
{
struct adv7170 *encoder = to_adv7170(p);


v4l2_dbg(1, debug, p, "set norm %llx\n", (unsigned long long)std);


if (std & V4L2_STD_NTSC) {
adv7170_write_block(sd, init_NTSC, sizeof(init_NTSC));  //这里调用的
        ... ...
}



猜你喜欢

转载自blog.csdn.net/yunjie167/article/details/80846802
今日推荐