标签:
转自:http://atu82.bokee.com/6706799.html
结构体嵌套结构体名
前一段时间在看DDK中例子的时候,看到这样的的结构体定义:
typedef struct _COMMON_DEVICE_DATA { PDEVICE_OBJECT Self; BOOLEAN IsFDO; ...... } COMMON_DEVICE_DATA, *PCOMMON_DEVICE_DATA; typedef struct _PDO_DEVICE_DATA { COMMON_DEVICE_DATA; // 注意这里 PDEVICE_OBJECT ParentFdo; PWCHAR HardwareIDs; ...... } PDO_DEVICE_DATA, *PPDO_DEVICE_DATA; typedef struct _FDO_DEVICE_DATA { COMMON_DEVICE_DATA; // 注意这里 PDEVICE_OBJECT UnderlyingPDO; ...... } FDO_DEVICE_DATA, *PFDO_DEVICE_DATA;
这里的结构体定义方法看起来好像是定义一个基类,然后在基类上扩展出两个子类。 这样的做法与平常的结构体嵌套结构体不同,因为在结构体中只有另外的结构体的名字,如PDO_DEVICE_DATA结构体中只有COMMON_DEVICE_DATA结构体名,而不是成员变量。这种写法在VC6.0中可以通过编译,在gcc中不能通过编译,因此我猜想可能微软扩展了C的语法,这种写法不是标准C的做法。
接下来,我写下面的例子程序来探讨这种定义结构体的方法。 在base.h中定义了三个结构体,BASE、EXT1、EXT2。EXT1和EXT2中都有BASE结构体名。发现嵌套了结构体名(BASE)的结构体(EXT1和EXT2)的长度是sizeof(BASE)+其它成员的长度。EXT1结构体指针可以直接访问BASE结构体的成员,且EXT1结构体指针可以强制转换成BASE结构体指针。
/* base.h */ #include <stdio.h> #include <stdlib.h> typedef unsigned char BOOLEAN; typedef unsigned long ULONG; typedef void VOID; #define FALSE 0; #define TRUE ~0; typedef struct _BASE { BOOLEAN IsExt1; ULONG Number; } BASE, *PBASE; typedef struct _EXT1 { BASE; ULONG Ext1Num; } EXT1, *PEXT1; typedef struct _EXT2 { BASE; ULONG Ext2Num; } EXT2, *PEXT2; VOID TestStruct() { BASE base, *pbase; EXT1 ext1, *pext1; EXT2 ext, *pext, *pext2; ext.Ext2Num = 2; ext.IsExt1 = FALSE; ext.Number = 100; pext = &ext; printf("sizeof(base) = %d\n", sizeof(base)); printf("sizeof(ext1) = %d\n", sizeof(ext1)); printf("sizeof(ext2) = %d\n", sizeof(ext)); pbase = (PBASE)pext; if (pbase->IsExt1) { printf("Is Ext1\n"); pext1 = (PEXT1)&ext; printf("Ext1Num = %ld\n", pext1->Ext1Num); } else { printf("Is Ext2\n"); pext2 = (PEXT2)&ext; printf("Ext2Num = %ld\n", pext2->Ext2Num); } } /* main.c */ #include "base.h" int main() { TestStruct(); return 0; }
标签:
原文地址:http://www.cnblogs.com/Acg-Check/p/4259151.html