c++ - 解析位图文件时,如何替换WORD和DWORD数据类型?

标签 c++ windows linux header bitmap

在 Windows 中,您可以在尝试解析 bmp 文件时包含 windows.h 头文件,并且数据类型 WORD 和 DWORD 是为您预定义的(根据我的阅读)。在 linux 中,我需要使用这些数据类型,但我不知道如何定义它们并且不能包含 windows.h header 。我如何在 C++ 中执行此操作?

最佳答案

包括<stdint.h> , 然后你可以便携地替换 WORDuint16_tDWORDuint32_t .和 BYTEuint8_t ,当然:

如果需要,可以添加以下代码:

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

但是要小心!如果你想要可移植,你必须记住多字节值的字节顺序。 Microsoft 代码几乎总是采用小端,但 Linux 可以在小端和大端机器上运行。

更新:

你在关于 BITMAPFILEHEADER 的评论中谈到的新问题与字段的类型无关,但与结构的打包相关:编译器可能会在结构中的字段之间添加填充字节以满足对齐(或其他要求)。

Microsoft 编译器将整数类型与其大小的地址倍数对齐。即 WORDSHORT值与 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 pragma(但要注意字节顺序):

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;

关于c++ - 解析位图文件时,如何替换WORD和DWORD数据类型?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/12334714/

相关文章:

c++ - 构建 Tensorflow 调试时出错 LNK2019

c++ - 父进程 "listening"到子消息

c++ - 多重定义错误

c++ - 如何在汇编级别分析 C++ 函数?

windows - 具有 NoBuffering 的 Haskell 跨平台 getChar

linux - 制作 : nothing can be done for all

c - 如何找到 PIE 二进制文件的加载重定位?

linux - 无法使用 input.h Linux 生成写入设备内核的击键

c++ - 相同的完整模板特化

c++ - 从 bool vector 返回索引的 int 函数