2013-11-26 4 views
0

Вот отрывок из ntdddisk.hЧто такое использование массивов одного элемента в структурах ddk?

typedef struct _DISK_GEOMETRY_EX { 
     DISK_GEOMETRY Geometry;         // Standard disk geometry: may be faked by driver. 
     LARGE_INTEGER DiskSize;         // Must always be correct 
     UCHAR Data[1];             // Partition, Detect info 
} DISK_GEOMETRY_EX, *PDISK_GEOMETRY_EX; 

Что такое точка UCHAR Data[1];? Почему не только UCHAR Data;? И в DDK есть много структур, которые имеют массивы одного элемента в объявлениях.

Спасибо, теперь ясно. Единственное, что не ясно, является реализация смещения. Это определяется как

#ifdef _WIN64 
#define offsetof(s,m) (size_t)((ptrdiff_t)&(((s *)0)->m)) 
#else 
#define offsetof(s,m) (size_t)&(((s *)0)->m) 
#endif 

Как это работает: ((s *)0)->m ???

Это

(size_t)&((DISK_GEOMETRY_EX *)0)->Data 

, как

sizeof (DISK_GEOMETRY) + sizeof(LARGE_INTEGER); 

Но есть два дополнительные вопрос:

1) Какое это? И почему мы должны использовать для этого &?

((DISK_GEOMETRY_EX *)0)->Data 

2) ((DISK_GEOMETRY_EX *)0)

Это дает мне 00000000. ли это convering для выравнивания адреса? интерпретировать его как адрес?

ответ

1

Очень распространенный в winapi, это переменная длина. Массив всегда является последним элементом в структуре и всегда содержит поле, которое указывает фактический размер массива. Растровое изображение, например, объявляется таким образом:

typedef struct tagBITMAPINFO { 
    BITMAPINFOHEADER bmiHeader; 
    RGBQUAD    bmiColors[1]; 
} BITMAPINFO, FAR *LPBITMAPINFO, *PBITMAPINFO; 

Таблица цветов имеет переменное количество записей, 2 для монохромного растрового изображения, 16 для 4bpp и 256 для 8bpp растрового изображения. Поскольку фактическая длина структуры изменяется, вы не можете объявить переменную этого типа. Компилятор не зарезервирует для этого достаточно места. Поэтому вам всегда нужен бесплатный магазин, чтобы выделить его, используя следующий код:

#include <stddef.h> // for offsetof() macro 
.... 

    size_t len = offsetof(BITMAPINFO, bmiColors) + 256 * sizeof(RGBQUAD); 
    BITMAPINFO* bmp = (BITMAPINFO*)malloc(len); 
    bmp->bmiHeader.biClrUsed = 256; 
    // etc... 
    //... 
    free(bmp); 

 Смежные вопросы

  • Нет связанных вопросов^_^