核心提示:
1. CR宏 (Containing Record):根据成员指针获取父结构体变量指针
2. 0 指针的妙用。
在EDKII 的代码中有不少关于CR宏的使用,如 时钟中断处理函数CoreTimerTick。
VOID EFIAPI CoreTimerTick ( IN UINT64 Duration ) { IEVENT *Event; ... if (!IsListEmpty (&mEfiTimerList)) { Event = CR (mEfiTimerList.ForwardLink, IEVENT, Timer.Link, EVENT_SIGNATURE); ... } }
CR宏的定义
- // CONTAINING_RECORD - returns a pointer to the structure
- // from one of it's elements.
- #define_CR(Record, TYPE, Field) ((TYPE *) ((CHAR8 *) (Record) - (CHAR8 *) &(((TYPE *) 0)->Field)))
- #defineCR(Record, TYPE, Field, Signature) \\par _CR(Record, TYPE, Field)
CR的用法: _CR ( 结构体某成员变量的指针 Record, 结构体类型定义 TYPE, 结构体成员变量名 Field );
这个宏定义的关键点是 0 指针。 结构体调用 Struct –> Member 是 把Struct的指针 加上 Member的偏移量, 0->member的调用可以直接得到 member的偏移量。 这样把member的实际指针 减去 偏移量,就是这个结构体本身的指针。 很巧妙的用法!
下面举例说明:
CR宏的使用
- #include"stdafx.h"
- #define CHAR8 char
- // CONTAINING_RECORD - returns a pointer to the structure
- // from one of it's elements.
- #define_CR(Record, TYPE, Field) ((TYPE *) ((CHAR8 *) (Record) - (CHAR8 *) &(((TYPE *) 0)->Field)))
- #defineCR(Record, TYPE, Field, Signature) \\par _CR(Record, TYPE, Field)
- typedefstruct_MyStruct
- {
- inta;
- charb;
- longc;
- intd;
- } MyStruct;
- int_tmain(intargc, _TCHAR* argv[])
- {
- MyStructmyStruct = {10,'a',30,25};
- printf("MyStruct Address 0x%x \n", &myStruct);
- MyStruct * pMyStruct = CR(&(myStruct.c), MyStruct, c, NULL);
- printf("pMyStruct Address 0x%x \n", pMyStruct);
- getchar();
- return 0;
- }