三维数组中的 C/C++ DWORD 到 BYTE 以及 BYTE 到 DWORD 转换

Nor*_*ros 3 c c++ arrays

我正在努力了解我是否以正确的方式执行此操作以及这是否是(唯一的)最佳解决方案。

我正在进行的项目是使用三维数组来保存和使用大量数据。“数据”的一部分是 DWORD 类型,我必须进行从/到 DWORD/BYTE 的安全转换。

BYTE(c 风格)数组如下所示:

BYTE array_data[150][5][255] = 
{
    {
        { // bytes },
        { 0x74,0x21,0x54,0x00 }, // This is converted from DWORD like: 0x00542174
        { // bytes },
        { // bytes },
        { // bytes },
    },
};
Run Code Online (Sandbox Code Playgroud)

我发现从 DWORD转换为 BYTE 的(唯一)方法:

DWORD dword_data;
char byte_array[4];

*(DWORD*)byte_array = dword_data; // byte_array becomes {0x74, 0x21, 0x54, 0x00}

wchar_t temp[256];

wsprintfW(temp, L"{0x%02x,0x%02x,0x%02x,0x%02x}, // This is converted from DWORD like: 0x%.8X\n", (BYTE)byte_array[0], (BYTE)byte_array[1], (BYTE)byte_array[2], (BYTE)byte_array[3], (DWORD)dword_data);
Run Code Online (Sandbox Code Playgroud)

据我所知,DWORD 是 4 BYTE,所以这就是为什么 char 最大长度是 4。(如果我错了,请纠正我?)

然后从 BYTE (s)转换回DWORD :

//Convert an array of four bytes into a 32-bit integer.
DWORD getDwordFromBytes(BYTE* b)
{
    return (b[0]) | (b[1] << 8) | (b[2] << 16) | (b[3] << 24);
};

printf("dword_data: 0x%.8X\n", getDwordFromBytes(array_data[0][1]));
Run Code Online (Sandbox Code Playgroud)

打印效果很好:0x00542174

所以我的问题是,这一切正确且安全吗?因为数组中有大量数据,并且 DWORD/BYTE 转换对我来说是必要的,所以它必须准确。

哪里做错了,请大家多多指教和指正,我将不胜感激!

Evg*_*Evg 5

这段代码

DWORD dword_data;
char byte_array[4];
*(DWORD*)byte_array = dword_data;
Run Code Online (Sandbox Code Playgroud)

根据 C++ 标准,这是未定义的行为。某些编译器可能允许将其作为扩展,但除非您希望在更改编译器或命令行选项时感到惊讶,否则不要使用它。

正确的做法是:

DWORD dword_data;
BYTE byte_array[sizeof(DWORD)];
memcpy(byte_array, &dword_data, sizeof(DWORD));
Run Code Online (Sandbox Code Playgroud)

不要担心效率:memcpy任何像样的编译器都会对此进行优化。

在 C++20 中,你将能够更加雄辩

auto byte_array = std::bit_cast<std::array<BYTE, sizeof(DWORD)>>(dword_data);
Run Code Online (Sandbox Code Playgroud)

memcpy向后转换也应该使用独立于字节序的方式来完成:您将无法在大字节序机器上getDwordFromBytes生成原始文件。dword_data