2017-07-10 4 views
0

Es gibt eine Struktur in einem COM-Header (vds.h) definiert ist:Com Interop Struktur Definition stimmt nicht überein Speicheraufteilung

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; 

ich kommentierten haben die Arten von einigen Feldern. Basierend auf dieser Headerdefinition scheint die Struktur 72 Bytes groß zu sein. Allerdings, wenn ich es in C# Marschall (I ein IntPtr auf ein Array dieser Strukturen erhalten) und im Speicher schauen, wo die IntPtr zeigt an, ich sehe dies:

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? 

Wie Sie sehen können, gibt es 2 4 Byte-Bereiche, die nicht berücksichtigt werden. Die C++ enum wird wie typedef enum _VDS_DISK_EXTENT_TYPE { deklariert, also glaube ich nicht, dass es 8 Bytes ist. Dasselbe gilt für die memberIdx, die als ULONG deklariert ist, also 4 Bytes. Wo ist dieses Padding definiert oder wo sind die Offsets für jedes definierte Feld? Es macht es fast unmöglich, die Objekte von dieser com-Assembly zu verwenden, wenn ich jeden im Speicher anzeigen und herausfinden muss, wo die wirklichen Grenzen zwischen den Feldern sind.

Antwort

1

Dies sieht wie ein Fall der Strukturelementausrichtung aus. Diese Struktur wurde speziell mit einer Ausrichtung von 8 Byte kompiliert, die die Standardeinstellung für Visual C++ ist. Beachten Sie, dass jedes Element an einer 8-Byte-Grenze beginnt. Wenn aufeinanderfolgende Elemente vorhanden wären, die kleiner als 8 Byte wären (z. B. zwei aufeinanderfolgende ULONG s), würden Sie die zusätzliche Auffüllung der ersten ULONG nicht sehen (weil 4-Byte-Elemente an 4-Byte-Grenzen ausgerichtet werden können, wenn ein Ausrichtungswert> = 4). Aber da Sie einen ULONG haben, gefolgt von einem ULONGLONG, wird das ULONG Mitglied aufgefüllt, so dass das folgende ULONGLONG Mitglied auf der 8-Byte-Grenze ausgerichtet ist (da 8-Byte-Mitglieder nicht auf 4-Byte-Grenzen ausgerichtet werden können).

https://msdn.microsoft.com/en-us/library/xh3e3fd0.aspx