我正在努力了解我是否以正确的方式执行此操作以及这是否是(唯一的)最佳解决方案。
我正在进行的项目是使用三维数组来保存和使用大量数据。“数据”的一部分是 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 转换对我来说是必要的,所以它必须准确。
哪里做错了,请大家多多指教和指正,我将不胜感激!
这段代码
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
| 归档时间: |
|
| 查看次数: |
6547 次 |
| 最近记录: |