LinuxÄں˻ù´¡Æª¡ª¡ªcontainer_ofÔÀíºÍÏÖʵӦÓÃ
LinuxÄÚºËÖо³£¿É¼ûcontainer_ofµÄÉíÓ°£¬ËüÔÚÏÖʵÇý¶¯µÄ±àдÖÐÒ²ÊÇÆÕ±éÓ¦Óá£
container_ofÔÀí
×÷ÓãºÍ¨¹ý½á¹¹ÌåµÄij¸ö³ÉÔ±±äÁ¿µØµãÕÒµ½¸Ã½á¹¹ÌåµÄÊ׵ص㡣
½ç˵ÈçÏ£º
/** * 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) );})
µÇ¼ºó¸´ÖÆ
ptr£º½á¹¹Ìå³ÉÔ±±äÁ¿µÄÖ¸Õë
type£º½á¹¹ÌåÀàÐÍ
member£º½á¹¹Ìå³ÉÔ±±äÁ¿µÄÃû×Ö
»»¾ä»°Ëµ£¬½Ð£ºÒÑÖª½á¹¹ÌåtypeµÄ³ÉÔ±memberµÄµØµãptr£¬Çó½â½á¹¹ÌåtypeµÄÆðʼµØµã¡£
ÅÌË㹫ʽΪ£ºtypeµÄÆðʼµØµã = ptr -size £¨sizeΪmemberµÄ´óС£©
ÒÔÒ»·ùͼ˵Ã÷ptr¡¢type¡¢memberµÄ¹Øϵ£º
ÔÀí¼òÊö£º
container_ofµÄÃî´¦¾ÍÔÚÓÚÒÔ0×÷Ϊ³ÉÔ±±äÁ¿memberµÄ»ùÖ·¡£
ÆäÖнç˵ÁËÒ»ÆäÖÐÑë±äÁ¿__mptr£¬”__”´ú±íÄÚ²¿Ê¹Ó㬡°m¡±´ú±ímiddle¡£
#define offsetof(TYPE, MEMBER) ((size_t) &((TYPE *)0)->MEMBER)
µÇ¼ºó¸´ÖÆ
typeof( ((type *)0)->member )ÊÇ»ñÈ¡memberµÄÀàÐÍ£¬__mptr = (ptr)ÅжÏptrÓëmemberÊÇ·ñΪͳһÀàÐÍ£¬offsetofÅÌËã³ÉÔ±memberµÄ¾Þϸsize¡£
Çý¶¯ÖеÄÏÖʵÀý×Ó
ÀýÈçÄں˵ÄpwmÇý¶¯£¬Í¨¹ý³ÉÔ±±äÁ¿chip£¬ÕÒµ½½á¹¹Ìåbcm2835_pwm£º
struct bcm2835_pwm { struct pwm_chip chip; struct device *dev; void __iomem *base; struct clk *clk; }; static inline struct bcm2835_pwm *to_bcm2835_pwm(struct pwm_chip *chip_ptr) { return container_of(chip_ptr, struct bcm2835_pwm, chip); }
µÇ¼ºó¸´ÖÆ
ʹÓÃcontainer_ofͨ³£¶¼»á½ç˵һ¸öº¯Êý£¬²¢ÇÒÃüÃûΪto_xxx»òÕßto_find_xxx£¬´ú±íÒªÕÒxxxÕâ¸ö½á¹¹Ì壬´«²ÎÔò´«Èë³ÉÔ±±äÁ¿Ö¸Õ룬ÁíÍ⺯ÊýÒ²»áÉùÃ÷Ϊinline¡£
ÒÔÉϾÍÊÇLinuxÄں˻ù´¡Æª¡ª¡ªcontainer_ofÔÀíºÍÏÖʵӦÓõÄÏêϸÄÚÈÝ£¬¸ü¶àÇë¹Ø×¢±¾ÍøÄÚÆäËüÏà¹ØÎÄÕ£¡