简体   繁体   English

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

[英]C/C++ DWORD to BYTE and BYTE to DWORD conversion in Three-Dimensional Array

I am struggling to understand if I am doing this the correct way and if this is the (only) best solution.我很难理解我是否以正确的方式执行此操作,以及这是否是(唯一)最佳解决方案。

The project I am working on is using a Three-Dimensional Array to hold and use lots of data.我正在进行的项目是使用三维数组来保存和使用大量数据。 One part of the "data" is DWORD type and I must have a safe conversion from/to DWORD/BYTE. “数据”的一部分是 DWORD 类型,我必须从/到 DWORD/BYTE 进行安全转换。

The BYTE (c style) array looks like this: BYTE(c 样式)数组如下所示:

BYTE array_data[150][5][255] = 
{
    {
        { // bytes },
        { 0x74,0x21,0x54,0x00 }, // This is converted from DWORD like: 0x00542174
        { // bytes },
        { // bytes },
        { // bytes },
    },
};

The (only) way to convert from DWORD to BYTE (s) I found:我发现从 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);

From I understand DWORD is 4 BYTE so that's why the char max length is 4. (correct me if I`m wrong?)据我了解,DWORD 是 4 BYTE,所以这就是字符最大长度为 4 的原因。(如果我错了,请纠正我?)

Then to convert back to DWORD from BYTE (s):然后从 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]));

Which prints out fine: 0x00542174 .打印得很好: 0x00542174

So my question is, is all this correct and safe?所以我的问题是,这一切都是正确和安全的吗? Because I will have lots of data in the array and the DWORD/BYTE conversion for me is imperative, it must be accurate.因为我将在数组中有大量数据,并且 DWORD/BYTE 转换对我来说是必不可少的,所以它必须是准确的。

Please advise and correct me where I`m doing things wrong, I would very much appreciate it!请建议并纠正我做错的地方,我将不胜感激!

This code这段代码

DWORD dword_data;
char byte_array[4];
*(DWORD*)byte_array = dword_data;

is undefined behavior according to the C++ standard.根据 C++ 标准,是未定义的行为 Some compilers may allow it as an extension, but unless you want to be surprised when you change a compiler or command line options, don't use it.一些编译器可能允许它作为扩展,但除非您想在更改编译器或命令行选项时感到惊讶,否则不要使用它。

The correct way is:正确的方法是:

DWORD dword_data;
BYTE byte_array[sizeof(DWORD)];
memcpy(byte_array, &dword_data, sizeof(DWORD));

Don't worry about efficiency: this memcpy will be optimized out by any decent compiler.不要担心效率:任何体面的编译器都会优化这个memcpy

In C++20 you'll be able to be more eloquent :在 C++20 中,您将能够更多 eloquent

auto byte_array = std::bit_cast<std::array<BYTE, sizeof(DWORD)>>(dword_data);

The backwards conversion should also be done using memcpy to be endianness-independent: your getDwordFromBytes will fail to produce the original dword_data on a big-endian machine.向后转换也应该使用memcpy来完成,使其与字节序无关:您的getDwordFromBytes将无法在大字节序机器上生成原始dword_data

DWORD is 32-bit unsigned integer. DWORD 是 32 位无符号 integer。

typedef unsigned long DWORD, *PDWORD, *LPDWORD;

32-bit means 4 bytes, because each byte is 8 bit. 32 位表示 4 个字节,因为每个字节是 8 位。 And 4*8=32 4*8=32

https://docs.microsoft.com/en-us/openspecs/windows_protocols/ms-dtyp/262627d8-3418-4627-9218-4ffe110850b2 https://docs.microsoft.com/en-us/openspecs/windows_protocols/ms-dtyp/262627d8-3418-4627-9218-4ffe110850b2

The problem will happen when you send your byte array to some code that expects to see those bytes in reversed order (different endianness).当您将字节数组发送到一些希望以相反顺序(不同字节序)查看这些字节的代码时,就会出现问题。 You would then need to reverse it.然后你需要扭转它。

DWORD is windows specific typedef, and all windows are little-endian, so I think it's safe to use this code as is, if you process data on the same machine. DWORD 是 windows 特定的 typedef,并且所有 windows 都是 little-endian,所以如果您在同一台机器上处理数据,我认为按原样使用此代码是安全的。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM