将结构复制到char[]缓冲区

Copy struct to char[] buffer

本文关键字:缓冲区 char 结构 复制      更新时间:2023-10-16

我必须将以下结构复制到char[]缓冲区。

 struct AMG_ANGLES {        
            unsigned char bIsEnCrypted;
            unsigned char bIsError;
            unsigned short      usErrorFlag;
            unsigned char byteNumDABs;
            unsigned short      usBagId;
            unsigned short      usKvMa;
            unsigned char byteDataType;
    };
            AMG_ANGLES struct_data;
            struct_data.bIsEnCrypted = 1;
            struct_data.bIsError = 1;
            struct_data.usErrorFlag = 2;
            struct_data.byteNumDABs = 1;
            struct_data.usBagId =10;
            struct_data.usKvMa=20;
            struct_data.byteDataType = 1;
// here I am coping structure to a char buffer
char sendbuf[sizeof(struct_data)] = "";
memcpy(sendbuf,(char*)&struct_data, sizeof(struct_data));

在复制时,缓冲区具有前两个无符号字符数据和short(1,1,2),大小仅为3字节。铰孔数据没有复制。请在我做错的地方帮忙。

我也尝试了以下方式

        memcpy(sendbuf+0, &struct_data.bIsEnCrypted, sizeof(struct_data.bIsEnCrypted));
        memcpy(sendbuf+1, &struct_data.bIsError, sizeof(struct_data.bIsError));
        memcpy(sendbuf+2, &struct_data.usErrorFlag, sizeof(struct_data.usErrorFlag));
        memcpy(sendbuf+4, &struct_data.byteNumDABs, sizeof(struct_data.byteNumDABs));
        memcpy(sendbuf+6, &struct_data.usBagId, sizeof(struct_data.usBagId));   
        memcpy(sendbuf+8, &struct_data.usKvMa, sizeof(struct_data.usKvMa));
        memcpy(sendbuf+10, &struct_data.byteDataType, sizeof(struct_data.byteDataType));

我得到了同样的结果。

您的代码很好;您确定缓冲区内容是否正确的方法是有缺陷的。

您没有告诉我们您是如何确定缓冲区的内容是错误的,但根据您的描述,我怀疑您做了类似printf( "%sn", sendbuf )的事情。好吧,这不起作用,因为缓冲区实际上并不包含字符,而是包含二进制数据。

具体来说,您的short usErrorFlag有两个字节长,由于您存储在其中的值是2,这意味着它将以两个连续的字节存储在sendbuf中,一个字节的值为0x02,下一个字节为0x00。(根据您描述中的提示,假设您的硬件是"Little Endian"。)因此,当您尝试将sendbuf的内容作为字符串查看时,printf()将在遇到0x00字节时立即停止打印。

因此,您的代码是正确的。继续将sendbuf发送到UDP套接字。

如果我读到"sendbuf",我会立即假设您正在将数据从一台计算机发送到另一台计算机。这些计算机将有不同的编译器,例如,编译器将以不同的顺序排列字节。memcpy不适用于所有编译器。

我建议您找到sendbuf内容的记录位置,并相应地分配各个字节。例如

sendbuf [0] = struct_data.bIsEncrypted;
sendbuf [1] = struct_data.bIsError;
sendbuf [2] = struct_data.uIsErrorFlag >> 8;
sendbuf [3] = struct_data.uIsErrorFlag & 0xff;

这使得你的代码独立于字节排序,独立于结构填充,一旦你不使用POD,就独立于项目的重新排序,等等。在你的情况下,我敢打赌,在byteNumDABs和usBagId之间至少有填充,并且在最后。

(字节2和3可能正好相反,这就是为什么你会找到该数据结构的规范)。