Core tips:
1. CR macro (containing Record): Gets the parent struct-body variable pointer based on the member pointer
2.0 pointers to the magical.
There are many uses of CR macros in Edkii code, such as the clock interrupt handler function Coretimertick.
VOID Efiapi Coretimertick (in UINT64 Duration ) { IEVENT *Event; ... if (! Islistempty (&mefitimerlist)) { =CR (Mefitimerlist.forwardlink, IEVENT, Timer.link, event_signature); ... }}
Definition of CR macro
- 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 )))
- #define CR (Record, TYPE, Field, Signature) \\par _CR (Record, TYPE, Field)
CR usage: _CR (pointer Record for a struct member variable, struct type definition type, struct member variable name Field);
The key point for this macro definition is the 0 pointer. struct call struct–> Member is the pointer to the struct and the Member offset, 0->member call can directly get the Member offset. This member the actual pointer minus the offset, which is the pointer to the struct itself. It's a clever use!
The following examples illustrate:
Use of CR macros
- #include "StdAfx.h"
- #define CHAR8 Char
- Containing_record-returns A pointer to the structure
- From one of it ' s elements.
- #define _CR field " ((TYPE *) (( CHAR8 *) (Record)-( CHAR8 *) & (((TYPE *) 0)-> field
- #define CR (Record, TYPE, Field, Signature) \\par _CR (Record, TYPE, Field)
- typedef struct _mystruct
- {
- int a ;
- Char b ;
- Long C ;
- int D ;
- } mystruct;
- int _tmain (intargc, _tchar* argv[])
- {
- MyStruct MyStruct = {Ten,' 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;
- }
EDKII CR macro: Gets the parent struct-body variable pointer based on the member pointer