0

Windowsでは、bmpファイルを解析しようとするときにwindows.hヘッダーファイルを含めることができ、dataTypes WORDおよびDWORDは事前定義されています(私が読んだものから)。Linux では、これらの dataTypes を使用する必要がありますが、それらを定義する方法がわからず、windows.h ヘッダーを含めることができません。C++でこれを行うにはどうすればよいですか?

4

1 に答える 1

4

を含めると、ポータブルに と で置き換えること<stdint.h>ができます。そして、もちろん:WORDuint16_tDWORDuint32_tBYTEuint8_t

必要に応じて、次のコードを追加できます。

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

しかし、注意してください!移植可能にしたい場合は、マルチバイト値のエンディアンに注意する必要があります。Microsoft のコードはほとんど常にリトルエンディアンを想定していますが、Linux はリトルエンディアンとビッグ エンディアンの両方のマシンで実行できます。

更新

についてのコメントであなたが話しているあなたの新しい問題BITMAPFILEHEADERは、フィールドのタイプではなく、構造体のパッキングに関連しています: コンパイラは、配置 (またはその他の要件) を満たすために、構造体のフィールド間にパディング バイトを追加する場合があります。

Microsoft コンパイラは、整数型をそのサイズの倍数のアドレスに揃えます。つまり、WORDand のSHORT値はアドレスの 2 の倍数に、DWORDand の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 packMS コンパイラとの互換性としてのみ、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;
于 2012-09-08T21:42:19.627 に答える