Warning: file_get_contents(/data/phpspider/zhask/data//catemap/5/spring-mvc/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
c结构和memcpy(字节数组)_C_Structure_Microcontroller_Memcpy - Fatal编程技术网

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;