c结构和memcpy(字节数组)
我正在接收字节缓冲区数组并尝试将其复制到结构: 我的结构是:c结构和memcpy(字节数组),c,structure,microcontroller,memcpy,C,Structure,Microcontroller,Memcpy,我正在接收字节缓冲区数组并尝试将其复制到结构: 我的结构是: typedef struct mydata_block { uint8_t cmd; uint32_t param; char str_buf[10]; uint32_t crc32; } mydata_t; 首先,发送数据的程序如下所示: blockTX.cmd=2 blockTX.str_buf=“eee789” blockTX.param=1001 blockTX.crc32=349407452
typedef struct mydata_block
{
uint8_t cmd;
uint32_t param;
char str_buf[10];
uint32_t crc32;
} mydata_t;
首先,发送数据的程序如下所示:
blockTX.cmd=2
blockTX.str_buf=“eee789”
blockTX.param=1001
blockTX.crc32=3494074521
-
02-00-00-00-E9-03-00-00-65-65-37-38-39-00-00-00-00-00-00-99-58-43-D0
收到数据后,我会使用下面的memcpy代码将数据复制到结构中:
memcpy((uint8_t *)&blockRX,(uint8_t *)usbd_cdc_buffer,sizeof(blockRX));
一切看起来都很好,但不是CMD(它的1字节,但有填充物?在结构中)?我如何解决这个问题?< /P> < P>传输数据需要考虑填充、大小、字节数等,所以你需要正确地生成和解析字节流。您可以使用GoogloeProtobuf之类的东西来序列化和反序列化您的数据
但是,如果必须这样做,您可以为该结构赋予packed属性。这将删除所有填充和对齐限制。这使您可以memcpy()
不填充结构,但代价是访问结构本身成员的速度变慢。这样做只有两个很好的理由:
传输数据需要考虑填充、大小、字节数等,因此需要正确生成和解析字节流。您可以使用GoogloeProtobuf之类的东西来序列化和反序列化您的数据
但是如果必须,可以给结构填充属性。这将删除所有填充和对齐限制。这使您可以memcpy()
不填充结构,但代价是访问结构本身成员的速度变慢。这样做只有两个很好的理由:
不要使用memcpy。您需要单独解析字节流,“理解”值,并将它们显式地、单独地写入结构的成员。任何关于填充、大小、endianess等的假设都会使您的程序不可移植,并且在将来很容易失败。可能存在填充,因为它是特定于编译器的。我关心类型的混合,例如
blockTX.str_buf=“eee789”
不是复制字符串的方法,您应该使用strcpy
@cdarke哦,很抱歉,blockTX代码不是它在pc中的c代码。。实际上是:blockTX.str_buf=Encoding.ASCII.GetBytes(“eee789”);但是我把它分条只是为了显示数据而不是代码。时间越长,速度越慢。但长-慢-纠正比短-快-错误或短-快-不可重用要好。修改代码以理解新的消息结构的需要也是如此。@AndrewHenle这是一个很好的观点。让我们在“即使更长更慢”的问题上达成妥协不要使用memcpy。您需要单独解析字节流,“理解”值,并将它们显式地、单独地写入结构的成员。任何关于填充、大小、endianess等的假设都会使您的程序不可移植,并且在将来很容易失败。可能存在填充,因为它是特定于编译器的。我关心类型的混合,例如blockTX.str_buf=“eee789”
不是复制字符串的方法,您应该使用strcpy
@cdarke哦,很抱歉,blockTX代码不是它在pc中的c代码。。实际上是:blockTX.str_buf=Encoding.ASCII.GetBytes(“eee789”);但是我把它分条只是为了显示数据而不是代码。时间越长,速度越慢。但长-慢-纠正比短-快-错误或短-快-不可重用要好。修改代码以理解新的消息结构的需要也是如此。@AndrewHenle这是一个很好的观点。让我们在“即使更长更慢”的问题上达成妥协此外,打包结构可能导致代码无法运行。因为x86允许,它被大量使用。其他硬件不允许不受限制地访问未对齐的数据。如果打包创建的代码无法运行,则编译器将被破坏。packed属性告诉编译器结构不使用填充或对齐。这也意味着对结构的任何成员的访问都必须处理未对齐的访问。例如,在ARM上读取一个struct{int x;}\uu属性((压缩))
会导致4个单独的字节读取、移位和OR。因此,速度要慢得多#pragma pack
在许多非x86平台上玩火。请注意,您仍然存在endianness问题。@AndrewHenle其中没有关于结构访问被破坏的内容。在获取压缩结构的成员地址时,您必须始终将指针指向压缩结构,例如typedef struct{int32_t unaligned_int32;}uu_属性((压缩))unaligned_uint32p代码>此外,打包结构可能导致代码无法运行。因为x86允许,它被大量使用。其他硬件不允许不受限制地访问未对齐的数据。如果打包创建的代码无法运行,则编译器将被破坏。packed属性告诉编译器结构不使用填充或对齐。这也意味着对结构的任何成员的访问都必须处理未对齐的访问。例如,在ARM上读取一个struct{int x;}\uu属性((压缩))
会导致4个单独的字节读取、移位和OR。因此,速度要慢得多#pragma pack
在许多非x86平台上玩火。请注意,您仍然存在endianness问题。@AndrewHenle其中没有关于结构访问被破坏的内容。在获取压缩结构的成员地址时,必须始终将指针指向压缩结构,例如typedef struct{int32\t unaligned\u int32;