网站建设 预算,江华网站建设,新型建筑模板,深圳市网络seo推广平台写在前面
本系列文章的灵感出处均是各个技术书籍的读后感#xff0c;详细书籍信息见文章最后的参考文献
CONTAINER_OF
在书中发现一个很有意思的宏#xff0c;以此可以衍生出来其很多的用法#xff0c;这个宏可以根据某个成员变量的地址得到包含这个成员变量地址的对象的…写在前面
本系列文章的灵感出处均是各个技术书籍的读后感详细书籍信息见文章最后的参考文献
CONTAINER_OF
在书中发现一个很有意思的宏以此可以衍生出来其很多的用法这个宏可以根据某个成员变量的地址得到包含这个成员变量地址的对象的地址。但是这个过程很危险慎用哦
我们先看这个宏的一个依赖宏OFFSET_OF它可以方便的获取此成员变量在这个对象之中的偏移量。
/** brief OFFSET_OF 获得member在type类型里面的偏移量* param[in] Type: 类型* param[in] MEMBER: 成员变量的名称*/
#define OFFSET_OF(TYPE, MEMBER) ((size_t)(static_castTYPE *(0))-MEMBER)而CONTAINER_OF宏可以给定一个成员变量的地址指定这个成员变量属于哪个对象指定这个成员变量在对象之中的名称。
/*** brief CONTAINER_OF - 通过三个参数返回指向数据结构的指针* param[in] ptr: 数据结构中指向某一成员的指针* param[in] type: 数据结构类型* param[in] member: 在数据结构中的成员* note CONTAINER_OF 可以根据某个成员变量的地址得到包含这个成员变量地址的对象的地址。这个过程很危险慎用哦* return 成员变量的地址*/
#define CONTAINER_OF(ptr, type, member) ({ \const typeof( (static_casttype*(0))-member ) *__mptr (ptr); \(type *)((char*)__mptr - OFFSET_OF(type,member) );})
Demo
int main(){foo my_foo;foo *p CONTAINER_OF(my_foo.a, struct foo, a);coutpendl;
}输出 0x7ffc75b6dfc0 其他用法
根据作者在书中所属这个宏被用于以下几种情形
引用计数对于引用计数结构可以传递给引用计数一个回调函数回调函数之中根据这个引用计数对象的地址倒推出包含引用计数的父对象的地址从而释放资源
//这依赖myref_是对象的公有成员变量
void object_release(struct* ref){Object* object CONTAINER_OF(ref, Object, myref_);free(object);
}无关类型的双向链表只要链表的元素之中包含这个node_ 指针我们在释放的时候其实就可以便利node_调用CONTAINER_OF 去获取这个元素的地址从而释放资源。
class Object{
public:some object...NodeUnit *node_;
};参考文献 《存储技术原理分析》第二章 Linux驱动模型