转载时请注明出处和作者联系方式
作者联系方式:李先静 <xianjimli at hotmail dot com>
最近在阅读linux kernel的代码,发现很多地方都使用了一个名container_of的宏,根据上下文可以看出,它的功能是得到包含某个结构成员的结构的指针,看了一下宏的定义,原来并没有用什么高深的技巧,只是C语言中常识而已,其实现如下:
(kernel.h)
#define
offsetof(TYPE, MEMBER) ((size_t) &((TYPE *)0)->MEMBER)
![](https://i-blog.csdnimg.cn/blog_migrate/6810355c2f78c12e91b7997a8e8c583a.gif)
#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
)
![](https://i-blog.csdnimg.cn/blog_migrate/6810355c2f78c12e91b7997a8e8c583a.gif)
![](https://i-blog.csdnimg.cn/blog_migrate/6810355c2f78c12e91b7997a8e8c583a.gif)
#define
COMPOSITE_OFFSET(ClassName, BaseName, MemberType, MemberName)
(DWORD(static_cast
<
BaseName
*>
(reinterpret_cast
<
MemberType
*>
(
0x10000000
+
offsetof(ClassName, MemberName))))
-
0x10000000
)
![](https://i-blog.csdnimg.cn/blog_migrate/6810355c2f78c12e91b7997a8e8c583a.gif)
#define
BEGIN_INTERFACE_TABLE(ClassName)
typedef ClassName _InterfaceTableClassName;
static
const
INTERFACE_ENTRY
*
GetInterfaceTable(
void
)
![](https://i-blog.csdnimg.cn/blog_migrate/a41954a27d6ad96fa2c2cf816e677448.gif)
...
{
![](https://i-blog.csdnimg.cn/blog_migrate/37c8bf68cdc3cc81759c34160776bc53.gif)
static const INTERFACE_ENTRY table[] = ...{
![](https://i-blog.csdnimg.cn/blog_migrate/6a9c071a08f1dae2d3e1c512000eef41.gif)
#define INTERFACE_TABLE_ENTRY(piid, pfn, dwData)
![](https://i-blog.csdnimg.cn/blog_migrate/37c8bf68cdc3cc81759c34160776bc53.gif)
...{ piid, pfn, dwData },
![](https://i-blog.csdnimg.cn/blog_migrate/6a9c071a08f1dae2d3e1c512000eef41.gif)
![](https://i-blog.csdnimg.cn/blog_migrate/6a9c071a08f1dae2d3e1c512000eef41.gif)
#define IMPLEMENTS_INTERFACE(ItfName)
![](https://i-blog.csdnimg.cn/blog_migrate/37c8bf68cdc3cc81759c34160776bc53.gif)
...{ &IID_##ItfName, ENTRY_IS_OFFSET, BASE_OFFSET(_InterfaceTableClassName, ItfName) },
![](https://i-blog.csdnimg.cn/blog_migrate/6a9c071a08f1dae2d3e1c512000eef41.gif)
![](https://i-blog.csdnimg.cn/blog_migrate/6a9c071a08f1dae2d3e1c512000eef41.gif)
#define IMPLEMENTS_INTERFACE_AS(RequestedItfName, BaseClassName)
![](https://i-blog.csdnimg.cn/blog_migrate/37c8bf68cdc3cc81759c34160776bc53.gif)
...{ &IID_##RequestedItfName, ENTRY_IS_OFFSET , BASE_OFFSET(_InterfaceTableClassName, BaseClassName)},
![](https://i-blog.csdnimg.cn/blog_migrate/6a9c071a08f1dae2d3e1c512000eef41.gif)
![](https://i-blog.csdnimg.cn/blog_migrate/6a9c071a08f1dae2d3e1c512000eef41.gif)
#define IMPLEMENTS_INTERFACE_WITH_COMPOSITE(RequestedItfName, DataMemberType, DataMemberName)
![](https://i-blog.csdnimg.cn/blog_migrate/37c8bf68cdc3cc81759c34160776bc53.gif)
...{ &IID_##RequestedItfName, ENTRY_IS_OFFSET , COMPOSITE_OFFSET(_InterfaceTableClassName, RequestedItfName, DataMemberType, DataMemberName) },
![](https://i-blog.csdnimg.cn/blog_migrate/6a9c071a08f1dae2d3e1c512000eef41.gif)
![](https://i-blog.csdnimg.cn/blog_migrate/6a9c071a08f1dae2d3e1c512000eef41.gif)
#define END_INTERFACE_TABLE()
![](https://i-blog.csdnimg.cn/blog_migrate/37c8bf68cdc3cc81759c34160776bc53.gif)
...{ 0, 0, 0 }
};
return table;
}