如何将来自struct的一些信息打包到2个字节的缓冲区中?

时间:2019-05-04 11:38:08

标签: c

我有这种形式的结构:

struct args {
  uint16_t portnum;   /**< port number */
  const char *portstr;/**< port number as string */
  cmd_t cmd;          /**< command (GET, SET) */
  uint8_t value;      /**< set value */
  uint8_t id;         /**< device id */
};

struct args arguments =
    { DEFAULT_PORTNUM, DEFAULT_PORTNUM_STR, UNDEF, 0, 0 };

我需要从参数中提取“ id,cmd,value”,并以这种形式将它们保存在2个字节的缓冲区中:

image

arguments.value的最大值为127,因此未使用第7位

我试过了,但是没用

uint8_t buf[2];
buf[0] = arguments.cmd | arguments.id << 2;
buf[1] = arguments.value >> 1;

if(send(sockfd, buf, 2, 0) < 0 ){
   //error
}

2 个答案:

答案 0 :(得分:1)

  

cmd_t是枚举typedef枚举{GET = 0,SET = 1,UNDEF = 2} cmd_t;
  ID∈[0,63],
  值∈[0,127]

请勿将value向右移动。 >> 1在逻辑上等于2除以/ 2

buf[0] = arguments.cmd | arguments.id << 2;
buf[1] = arguments.value;

buf[1]的MSB位为“未使用”-将从arguments.value开始设置为零。

请记住,最好实施断言或其他错误检查机制以使您的功能更加安全:

assert(0 <= arguments.cmd && arguments.cmd <= 2);
assert(0 <= arguments.id && arguments.id <= 63);
assert(0 <= arguments.value && arguments.value <= 127);

您可以掩盖这些值,以免发生任何奇怪的事情,如@bolson在其答案中所建议的

buf[0] = (arguments.cmd & 0x3) | ((arguments.id << 2) & 0xfc);
buf[1] = arguments.value & 0x7f;

答案 1 :(得分:0)

通过掩盖您要保留或丢弃的位更加明确

buf[0] = (arguments.cmd & 0x03) | ((arguments.id & 0x3f) << 2);
buf[1] = (arguments.value >> 1) & 0x7f;