[英]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.