将 char[] 转换为 C++ 中的结构时,计算机会忽略一个字节

Posted

技术标签:

【中文标题】将 char[] 转换为 C++ 中的结构时,计算机会忽略一个字节【英文标题】:A byte is ignored by the computer when casting a char[] to a struct in C++ 【发布时间】:2022-01-05 17:14:12 【问题描述】:

我正在编写一个客户端-服务器程序,其中客户端是用 C++ 编写的,而服务器端是用 Python 编写的。

字节流从服务器端发送并接收到char[] 缓冲区,然后使用reinterpret_cast 转换为适当的结构。

char response_buffer[7];
recv(sock, response_buffer, 7, 0);
s_response* response = reinterpret_cast<s_response*>(response_buffer);
cout << response -> code << endl;

结构体是这样定义的:

typedef struct 
    unsigned char version;
    unsigned short code;
    unsigned int payload_size;
 s_response;

但不是version (1 字节) 得到response_buffer[0] 中的值,而code 得到response_buffer[1]response_buffer[2] (两个字节 ),code 最终得到response_buffer[2]response_buffer[3] 中的值,而payload_size 得到response_buffer[4]response_buffer[6],因此,值response_buffer[1] 不会插入到任何结构的属性中,并且结果是一团糟。

起初,我认为这是由于字节顺序,但是当我发送值 2200113821 时,例如,从服务器端来看,response_buffer中的值如下:

0. 00000010
1. 11101001
2. 00000011
3. 11111101
4. 00110101
5. 00000000
6. 00000000

我期望得到的,并且顺序正确。但是当我打印出response-&gt;code 时,我得到的值是64771,它是11111101 00000011(上面列表中的2 和3),而不是2001,它是00000011 11101001(列表中的1 和2)。意思是,当我将char* 转换为s_response* 时,response_buffer 中位置 1 的字节将被忽略,并且从那里开始的值从正确的顺序偏移了一个字节。

知道我做错了什么吗?

【问题讨论】:

此问题显示的代码不符合 *** 显示 minimal reproducible example 的要求。因此,这里的任何人都不太可能最终回答这个问题。但最多只能猜测。你需要edit你的问题来展示一个最小的例子,不超过一两页代码(“最小”部分),其他人都可以剪切/粘贴完全如图所示,编译、运行和重现所描述的问题(“可重现”部分,这包括任何辅助信息,如程序的任何输入)。请参阅How to Ask 了解更多信息。 另外,如果您尝试查看sizeof 的结构是什么,您可能会感到惊讶,并自己找出答案。 char response_buffer[7]; 可能不够大,无法容纳s_response 类型的对象(由于结构填充) - 您应该改用char response_buffer[sizeof(s_response)]; reinterpret_cast&lt;s_response*&gt;(response_buffer) 看起来像 UB。 如果你使用 TCP,你需要检查你收到了多少,只有当你得到足够的时候才能解析数据。 【参考方案1】:

正如 cmets 中所写,是结构填充造成了问题。 如下图添加#pragmas即可解决

#pragma pack(push,1)
typedef struct 
    unsigned char version;
    unsigned short code;
    unsigned int payload_size;
 s_response;
#pragma pack(pop)

【讨论】:

以上是关于将 char[] 转换为 C++ 中的结构时,计算机会忽略一个字节的主要内容,如果未能解决你的问题,请参考以下文章

C++ 编译时提示:不能将参数 1 从“char [6]”转换为“LPCTSTR”

将C的char数组转换为C++的字符串

C++ 我将一个const char*的字符串转换为string出错

在 C++ 中使用 atoi 将 char 数组转换为 int 值

C++怎么将 CString 转换成 unsigned char 的数组

C++ boost.python 无法将 const char* 转换为 str