在UEFI的code裡看到很多這樣的用法, 所以追根究底把它弄懂。用法是: 如果傳進一個函數裡面是某個結構成員的位址,可以用這個巨集回推出主結構的起始位址。
+ /*
+ 原始定義:
+ #define _CR(Record, TYPE, Field)
+ ((TYPE *) ((CHAR8 *) (Record) - (CHAR8 *) &(((TYPE *) 0)->Field)))
+
+ 用途: 由結構成員的位址求得整個結構的起始位址
+
+ Record:該成員的位址
+ TYPE:該成員所屬結構的型態
+ Field:該成員
+ (CHAR8 *) (Record):該TYPE結構成員的實際位址
+ (CHAR8 *) &( ( (TYPE *) 0)->Field):該成員在結構中的相對偏移量
+
+ 兩個做相減之後便可取得結構頭的位址,最後以(TYPE *)作強制轉換。
+
+ */
+
+ #define _CR(Record, TYPE, Field)
+ ((TYPE *) ((char *) (Record) - (char *) &( ((TYPE *)0)->Field)) )
+
+ typedef struct _MyStru {
+ char a;
+ char b;
+ char c;
+ } MY_TYPE;
+
+ void main()
+ {
+ MY_TYPE *pd;
+
+ printf("Find pd address by CR: %X \n", _CR(&(pd->c), MY_TYPE, c) );
+ printf("pd address: %X \n", pd );
+ }
沒有留言:
張貼留言