将struct复制到char []缓冲区

时间:2015-12-01 11:04:48

标签: c++ structure memcpy

我必须将以下结构复制到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));

复制具有前两个无符号字符数据和短(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));

我得到的结果相同。

2 个答案:

答案 0 :(得分:3)

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

你没有告诉我们你是如何确定缓冲区的内容是错误的,但是根据你的描述,我怀疑你做了printf( "%s\n", sendbuf )之类的事情。好吧,那不行,因为你的缓冲区实际上并不包含字符,它包含二进制数据。

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

所以,你的代码是正确的。继续将sendbuf发送到UDP套接字。

答案 1 :(得分:2)

如果我读“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;

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

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