扫一扫
分享文章到微信
扫一扫
关注官方公众号
至顶头条
最近在阅读linux kernel的代码,发现很多地方都使用了一个名container_of的宏,根据上下文可以看出,它的功能是得到包含某个结构成员的结构的指针,看了一下宏的定义,原来并没有用什么高深的技巧,只是C语言中常识而已,其实现如下:
(kernel.h)
#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) );})
想起以前学习COM时,看过< COM本质论>,里面提到了类似的方法:
(COM本质论:inttable.h)
#define BASE_OFFSET(ClassName, BaseName) \
(DWORD(static_cast<BaseName*>(reinterpret_cast<ClassName*>(0x10000000))) - 0x10000000)
#define COMPOSITE_OFFSET(ClassName, BaseName, MemberType, MemberName) \
(DWORD(static_cast<BaseName*>(reinterpret_cast<MemberType*>(0x10000000 + offsetof(ClassName, MemberName)))) - 0x10000000)
#define BEGIN_INTERFACE_TABLE(ClassName) \
typedef ClassName _InterfaceTableClassName;\
static const INTERFACE_ENTRY *GetInterfaceTable(void) \
{\
static const INTERFACE_ENTRY table[] = {\
#define INTERFACE_TABLE_ENTRY(piid, pfn, dwData) \
{ piid, pfn, dwData },
#define IMPLEMENTS_INTERFACE(ItfName) \
{ &IID_##ItfName, ENTRY_IS_OFFSET, BASE_OFFSET(_InterfaceTableClassName, ItfName) },
#define IMPLEMENTS_INTERFACE_AS(RequestedItfName, BaseClassName) \
{ &IID_##RequestedItfName, ENTRY_IS_OFFSET , BASE_OFFSET(_InterfaceTableClassName, BaseClassName)},
#define IMPLEMENTS_INTERFACE_WITH_COMPOSITE(RequestedItfName, DataMemberType, DataMemberName) \
{ &IID_##RequestedItfName, ENTRY_IS_OFFSET , COMPOSITE_OFFSET(_InterfaceTableClassName, RequestedItfName, DataMemberType, DataMemberName) },
#define END_INTERFACE_TABLE() \
{ 0, 0, 0 }\
};\
return table;\
}
如果您非常迫切的想了解IT领域最新产品与技术信息,那么订阅至顶网技术邮件将是您的最佳途径之一。
现场直击|2021世界人工智能大会
直击5G创新地带,就在2021MWC上海
5G已至 转型当时——服务提供商如何把握转型的绝佳时机
寻找自己的Flag
华为开发者大会2020(Cloud)- 科技行者