容器机制

定义

linux中的容器机制,是通过container_of宏来实现的。

// include/linux/stddef.h
#undef offsetof
#ifdef __compiler_offsetof
#define offsetof(TYPE, MEMBER)  __compiler_offsetof(TYPE, MEMBER)
#else
#define offsetof(TYPE, MEMBER)  ((size_t)&((TYPE *)0)->MEMBER)
#endif

// include/linux/kernel.h
/**
 * 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) ({              \
    void *__mptr = (void *)(ptr);                   \
    BUILD_BUG_ON_MSG(!__same_type(*(ptr), ((type *)0)->member) &&   \
             !__same_type(*(ptr), void),            \
             "pointer type mismatch in container_of()");    \
    ((type *)(__mptr - offsetof(type, member))); })

用途

根据指定对象的指定字段的指针,获取该指针对应的外部对象。

原理

对象内存布局与指针运算。


对象内存布局

所谓对象的内存布局,就是内存中对象各个字段的排列关系。这个关系在代码编译过程中已经确定。这种关系确定之后,对象中各个属性相对于对象的偏移量也就确定了。

要理解指针运算,首先要理解什么是指针。指针可以理解为虚拟内存地址中一个具体的值,这个值表示了数据在内存中的一个具体位置。指针运算,就是通过对某个指针进行加减操作,来确定一个其他的位置。

container_of宏定义了以下步骤来实现:

  • 将传入的ptr参数解释成任意指针,为后续进行指针运算做准备。
  • 将数字0转化为指定类型的指针,获取该指针对应的字段的值,将该值取地址后强制转换为size_t类型。
  • 对ptr指针进行减法运算,而后强制类型转换为指定类型。

实际上,就是假定在虚拟内存地址0处有一个指定类型的对象,通过该对象可以获取到指定字段的偏移量。而后,对实际的指针减去偏移量,来获取到其对应的指定类型的对象。

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
【社区内容提示】社区部分内容疑似由AI辅助生成,浏览时请结合常识与多方信息审慎甄别。
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

相关阅读更多精彩内容

友情链接更多精彩内容