Windowsでは、bmpファイルを解析しようとするときにwindows.hヘッダーファイルを含めることができ、dataTypes WORDおよびDWORDは事前定義されています(私が読んだものから)。Linux では、これらの dataTypes を使用する必要がありますが、それらを定義する方法がわからず、windows.h ヘッダーを含めることができません。C++でこれを行うにはどうすればよいですか?
1 に答える
を含めると、ポータブルに と で置き換えること<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
and のSHORT
値はアドレスの 2 の倍数に、DWORD
and の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;
フィールドのサイズは 4 バイトであるため、4 の倍数にアラインされることに注意してくださいbfSize
。構造体のオフセット 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 コンパイラとのみサポートします。
完全に移植可能にしたい場合は、構造体を直接読み取る必要がありますが、バイトをストリームとして読み取り、値を 1 つずつ作成します (2 バイトをbfType
に読み取り、4 バイトを に読み取るbfSize
など)。
他の Linux に移植したい場合は、GCC プラグマを使用できます (ただし、エンディアンに注意してください)。
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;