在COM标头(vds.h)中定义了一个结构:
typedef struct _VDS_DISK_EXTENT
{
// A Guid
VDS_OBJECT_ID diskId;
// An Enum, with the largest defined value 0x7FFF
VDS_DISK_EXTENT_TYPE type;
ULONGLONG ullOffset;
ULONGLONG ullSize;
// Guid
VDS_OBJECT_ID volumeId;
//Guid
VDS_OBJECT_ID plexId;
ULONG memberIdx;
} VDS_DISK_EXTENT;
我注释了一些字段的类型。根据此标头定义,结构看起来大72字节。但是,当我在C#中编组它时(我得到一个IntPtr到这些结构的数组)并查看IntPtr指示的内存,我看到了:
0x01717A50 a8 c5 af 28 37 e1 0d 43 -> diskId
0x01717A58 b0 87 e2 ef 94 5f 9f 27 -> diskId
0x01717A60 02 00 00 00 00 00 00 00 -> first 4 bytes are extent type, second 4?
0x01717A68 00 00 70 23 00 00 00 00 -> offset
0x01717A70 00 00 50 4d 74 00 00 00 -> size
0x01717A78 38 3c 22 26 e9 de df 44 -> volumeId
0x01717A80 81 f3 ba ee af e2 ad 2b -> volumeId
0x01717A88 48 98 78 bb 7f dd bc 41 -> plexId
0x01717A90 94 17 db d2 86 01 54 ce -> plexId
0x01717A98 00 00 00 00 00 00 00 00 -> first 4 bytes are membderIdx, second 4?
如您所见,有2个4字节区域未计入。 c ++枚举声明为typedef enum _VDS_DISK_EXTENT_TYPE {
,所以我不认为它是8个字节。与memberIdx相同,它被声明为ULONG,因此它是4个字节。这个填充定义在哪里或每个字段的偏移定义在哪里?如果我必须在内存中查看每个对象并找出字段之间的真实边界,那么几乎不可能使用这个com程序集中的对象。
答案 0 :(得分:1)
这看起来像结构成员对齐的情况。具体来说,这个结构是使用8字节的对齐编译的,这是Visual C ++的默认值。请注意,每个成员都以8字节边界开头。如果连续成员小于8个字节(例如,连续两个ULONG
),则在第一个ULONG
上看不到额外的填充(因为4个字节的成员可以对齐)当使用对齐值> = 4时,在4字节边界上。但是,由于您有ULONG
后跟ULONGLONG
,因此填充ULONG
成员,以便后面的ULONGLONG
成员在8字节边界上对齐(因为8字节成员不能在4字节边界上对齐。)