如何使用具有动态变化的数据大小的结构? [英] How to use structure with dynamically changing size of data?

查看:116
本文介绍了如何使用具有动态变化的数据大小的结构?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

仅针对C的问题,C ++和向量不能解决问题.

Question for C only, C++ and vectors do not solve problem.

我有这样的结构:

typedef __packed struct Packet_s
{
  U8  head;
  U16 len;
  U32 id;
  U8  data;
  U8  end;
  U16 crc;
} Packet_t, *Packet_p;

( EDIT :U8是uint8_t(未签名字符),依此类推)

(EDIT: U8 is uint8_t (unsigned char) and so on)

例如,我收到了数据包(十六进制):

For example, I've received packet(hex):

24 0B 00 07 00 00 00 AA 0D 16 1C

24 0B 00 07 00 00 00 AA 0D 16 1C

其中

head = 0x24

head = 0x24

len = 0x0B 0x00

len = 0x0B 0x00

id = 0x07 0x00 0x00 0x00

id = 0x07 0x00 0x00 0x00

数据= 0xAA

end = 0x0D

end = 0x0D

crc = 0x16 0x1C

crc = 0x16 0x1C

我可以这样从传入缓冲区复制它

I can copy it from incoming buffer like this

U8 Buffer[SIZE]; // receives all bytes here
memcpy(&Packet, &Buffer, buffer_len);

并进一步使用它.

如果字段"DATA"长于1个字节,是否可以使用我的结构?

我该如何处理这样的事情?

How can I handle something like this?

24 0F 00 07 00 00 00 AA BB CC DD EE 0D BD 66

24 0F 00 07 00 00 00 AA BB CC DD EE 0D BD 66

数据包的长度始终是已知的(2和3个字节具有有关长度的信息).

Length of packet will be always known (2 and 3 bytes have info about length).

在句柄"下,我想做下一步:

Under "handle" I mean that I want to do next:

  if (isCRCmatch() )
  {
    if(Packet.id == SPECIAL_ID_1)
    {
      // do something
    }

    if(Packet.id == SPECIAL_ID_2)
    {
      // do other 
    }

    if(Packet.data[0] == 0xAA)
    {
      // do one stuff
    }

    if(Packet.data[1] == 0xBB && Packet.id == SPECIAL_ID_3 )
    {
      // do another stuff
    }

  }

而且(如果可能的话)我也想使用相同的结构发送"anwers":

And also (if possible ofc) I would like to send "anwers" using same structure:

U8 rspData[] = {0x01, 0x02, 0x03, 0x04, 0x05, 0x06};

SendResponce(Packet.id, rspData);

void SendResponce (U8 id_rsp, uint8_t* data_rsp)
{
  Packet_t ResponceData;
  uint16_t crc;
  uint8_t *data;

  ResponceData.head  = 0x24;
  ResponceData.len   = sizeof(ResponceData); // HERE IS PROBLEM ONE
  ResponceData.id   = id_rsp;
  ResponceData.data  = *data_rsp; // HERE IS PROBLEM TWO
  ResponceData.end   = 0x0D; // symbol '\r'

  data = (uint8_t*)&ResponceData;
  crc = GetCrc(data, sizeof(ResponceData)-2); // last 2 bytes with crc

  ResponceData.crc = crc;//(ack_crc >> 8 | ack_crc);

  SendData((U8*)&ResponceData, sizeof(ResponceData));  // Send rsp packet
}

第一个问题-我无法自动获取所有结构的大小,因为指针将始终为4个字节... 第二个问题-因为我不知道结尾在哪里,所以我肯定会丢失rsp数据.

First problem - I cant get size of all structure automatically, since pointer will be always 4 bytes... Second problem - I sure that I will lose rsp data since I don't know where is end of it.

推荐答案

结构中间不能有动态缓冲区.

You can't have dynamic buffer in middle of a struct.

解决问题的另一种方法是将结构分为两部分. 例如(注意data在这里是灵活数组成员):

Another way to solve the problem is divide the struct to two pieces. For example (notice that data is here a flexible array member):

typedef __packed struct Packet_s
{
  U8  head;
  U16 len;
  U32 id;
  U8  data[];
} Packet_t, *Packet_p;

typedef __packed struct PacketEnd_s
{
  U8  end;
  U16 crc;
} PacketEnd_t, *PacketEnd_p;

然后使用

Packet_t *pPacket = (Packet_t *)&Buffer;
PacketEnd_t *pPacketEnd = (PacketEnd_t *)( count pointer here by using pPacket->len );

假设__packed允许对__packed结构的成员使用未对齐的访问.

Assuming that __packed allows to use unaligned access to members of __packed structs.

这篇关于如何使用具有动态变化的数据大小的结构?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆