zoukankan      html  css  js  c++  java
  • contain_of宏定义

     Container_of在Linux内核中是一个常用的宏,用于从包含在某个结构中的指针获得结构本身的指针,通俗地讲就是通过结构体变量中某个成员的首地址进而获得整个结构体变量的首地址。

    实现方式:

      container_of(ptr, type, member) ;

       其实它的语法很简单,只是一些指针的灵活应用,它分两步:

        第一步,首先定义一个临时的数据类型(通过typeof( ((type *)0)->member )获得)与ptr相同的指针变量__mptr,然后用它来保存ptr的值。

        第二步,用(char *)__mptr减去member在结构体中的偏移量,得到的值就是整个结构体变量的首地址(整个宏的返回值就是这个首地址)。

        其中的语法难点就是如何得出成员相对结构体的偏移量?

       

    通过例子说明,如清单1:

     1 #include <stdio.h>
     2 #define offsetof(TYPE, MEMBER) ((size_t) &((TYPE *)0)->MEMBER)
     3 #define  container_of(ptr, type, member) ({                      
     4                       const typeof( ((type *)0)->member ) *__mptr = (ptr);    
     5                        (type *)( (char *)__mptr - offsetof(type,member) );})
     6 struct test_struct {
     7            int num;
     8           char ch;
     9           float f1;
    10   };
    11  int main(void)
    12   {
    13           struct test_struct *test_struct;
    14           struct test_struct init_struct ={12,'a',12.3};
    15           char *ptr_ch = &init_struct.ch;
    16           test_struct = container_of(ptr_ch,struct test_struct,ch);
    17           printf("test_struct->num =%d
    ",test_struct->num);
    18           printf("test_struct->ch =%c
    ",test_struct->ch);
    19           printf("test_struct->ch =%f
    ",test_struct->f1);
    20           return 0;
    21   }

    或者Linux内核中的函数:

    struct eg2805_charger {
    	struct device *chg_dev;
    	struct i2c_client *client;
    	struct power_supply batt_psy;
    	struct power_supply *usb_psy;
    	struct workqueue_struct  *chg_workqueue;
    	struct delayed_work chg_delay_work;
    
    	bool	enable_chg;
    	bool	recharge;
    	unsigned int	chg_type;
    	unsigned int 	battery_present;
    	unsigned int 	online;
    	unsigned int 	temperature;
    	unsigned int 	voltage;
    	unsigned int	battery_status;
    	unsigned int	ichg;
    	unsigned int	aicr;
    	unsigned int	cv_value;
    	unsigned int 	batt_current;
    
    	struct qpnp_vadc_chip	*vadc_dev;
    
    	bool			batt_hot;
    	bool			batt_warm;
    	bool			batt_cool;
    	bool			batt_cold;
    	bool			batt_good;
    	int				usb_psy_ma;
    	struct mutex	icl_set_lock;
    };
    
    static void eg2805_charger_work(struct work_struct *work)
    {
    	u8 buf[50]={0};
    	int i=0;
    	int ret;
    	int temp, voltage;
    	int value = 0;
            //第一个参数为work,函数传参下来的;第二个参数为定义的结构体,第三个则是传参下来的里面需要的work_struct
    	struct eg2805_charger *eg2805_chg = container_of(work,
    				struct eg2805_charger,
                                    chg_delay_work.work);
    

      

  • 相关阅读:
    AGC005D ~K Perm Counting
    运行python脚本后台执行
    java枚举类型
    java可变参数长度
    java 泛型数组列表
    java抽象类
    java final使用
    java继承
    java 对象
    java 重载
  • 原文地址:https://www.cnblogs.com/linhaostudy/p/7966081.html
Copyright © 2011-2022 走看看