При синтаксическом анализе растровых файлов, как заменить типы данных WORD и DWORD?

В windows вы можете включить заголовочный файл windows.h при попытке разобрать bmp-файлы, и для вас предварительно определены dataTypes WORD и DWORD (из того, что я прочитал). В Linux мне нужно использовать эти dataTypes, но я не знаю, как их определить, и не могу включить заголовок windows.h. Как мне сделать это в C ++?

0

Решение

Включают <stdint.h>, а затем вы можете заменить портативно WORD с uint16_t а также DWORD с uint32_t, А также BYTE с uint8_t, конечно:

Если вы хотите, вы можете добавить следующий код:

#include <stdint.h>
typedef uint32_t DWORD;
typedef uint16_t WORD;
typedef uint8_t BYTE;

Но будьте осторожны! Если вы хотите быть переносимым, вы должны иметь в виду порядковый номер многобайтовых значений. Код Microsoft почти всегда подразумевает порядок байтов, но Linux может работать как на маленьких, так и на старших машинах.

ОБНОВИТЬ:

Ваша новая проблема, о которой вы говорите в комментариях о BITMAPFILEHEADER не относится к типу полей, но к упаковка структуры: компилятор может добавить байты заполнения между полями в структуре, чтобы удовлетворить выравнивание (или другие требования).

Компиляторы Microsoft выравнивают целочисленный тип по адресу, кратному его размеру. То есть, WORD а также SHORT значения выровнены по адресу, кратному 2, и DWORD а также LONG значения, кратные 4.

Если вы видите определение вашей структуры:

typedef struct {
WORD    bfType;      //offset 0
DWORD   bfSize;      //offset 4
WORD    bfReserved1; //offset 8
WORD    bfReserved2; //offset 10
DWORD   bfOffBits;   //offset 12
} BITMAPFILEHEADER;

Обратите внимание, что bfSize поле имеет размер 4 байта, поэтому оно будет выровнено по кратному 4. Вместо смещения 2 структуры оно будет смещено 4, добавляя 2 байта заполнения.

Теперь все заголовки Windows скомпилированы с опцией #pragma pack это говорит компилятору игнорировать ограничения выравнивания в полях структуры. Итак, первая структура на самом деле:

#pragma pack(push)
typedef struct {
WORD    bfType;      //offset 0
DWORD   bfSize;      //offset 2
WORD    bfReserved1; //offset 6
WORD    bfReserved2; //offset 8
DWORD   bfOffBits;   //offset 10
} BITMAPFILEHEADER;
#pragma pack(pop)

Компилятор GCC поддерживает #pragma pack только как совместимость с компиляторами MS и только с компиляторами x86.

Если вы хотите стать полностью переносимым, вы должны прочитать структуру напрямую, но прочитать байты как поток и построить значения одно за другим (считайте 2 байта в bfTypeпрочитайте 4 байта в bfSize, так далее.)

Если вы хотите перейти на другой Linux, вы можете использовать прагму GCC (но остерегайтесь endiannes):

typedef struct __attribute__((packed)) {
WORD    bfType;      //offset 0
DWORD   bfSize;      //offset 2
WORD    bfReserved1; //offset 6
WORD    bfReserved2; //offset 8
DWORD   bfOffBits;   //offset 10
} BITMAPFILEHEADER;
4

Другие решения

Других решений пока нет …

По вопросам рекламы ammmcru@yandex.ru
Adblock
detector