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