bloggerads

2014年6月9日 星期一

Demonstrate how macro CR works

在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 );  
+    }

沒有留言:

張貼留言