可变长结构体

经常遇到消息体变长问题,小总结一下。变长结构体的核心思想就是在结构体的最后一个数据结构为一个指针,这个指针指向的是这个结构体的末尾数据,说的有点绕,见下面结构体

typedef struct stru_tcp_server_msg
{
    uint32_ msgLength;  //消息体长度  此长度为整个消息长度,包括msgLength本身的长度
    uint32_ returnCode; //消息TcpServer返回码
    uint8_  zmqMsgBody[0];  //消息体
}TS_TCP_SERVER_MSG;

见上面zmqMsgBody[0]的定义,看起来很奇怪,其实它的作用就是指向这个结构体的末尾,他怎么使用呢?

typedef struct stru_zmq_server_msg
{
  uint32_ deviceId;
  uint32_ msgCode;
}TS_ZMQ_SERVER_MSG;

 int len = sizeof(TS_TCP_SERVER_MSG) + 
           sizeof(TS_ZMQ_SERVER_MSG);
    TS_TCP_SERVER_MSG* tdata = (TS_TCP_SERVER_MSG*)malloc(len);
    tdata->msgLength = len;
    tdata->returnCode = 0;
    TS_ZMQ_SERVER_MSG* data = (TS_ZMQ_SERVER_MSG*)tdata->zmqMsgBody;

    data->deviceId = 100;
    data->msgCode = TS_DEVICE_CONFIG_REQ_MSG;

就是这样,malloc一个sizeof(TS_TCP_SERVER_MSG) + sizeof(TS_ZMQ_SERVER_MSG)长度的数据块就可以了,如上代码tdata->zmqMsgBody所指向的就是TS_TCP_SERVER_MSG结构体的尾位置,也就是TS_ZMQ_SERVER_MSG的首位置。

还有一个为题就是,有时zmqMsgBody[0]这种定义有的编译器编译不过去,解决办法很简单改成zmqMsgBody[1]即可。但注意sizeof的大小会改变zmqMsgBody[0]时,这个项目是不算到结构体长度里面的,但是zmqMsgBody[1]会把这个项目的长度加到结构体长度,然后字节补齐(1字节对齐时不需要补齐),例如TS_TCP_SERVER_MSG结构体

[0]时: sizeof(TS_TCP_SERVER_MSG) = 8

[1]时: sizeof(TS_TCP_SERVER_MSG) = 8 + 1 + 3 = 12    //3为字节补齐

原文地址:https://www.cnblogs.com/dangerman/p/2820825.html