2016-07-28 77 views
0

我有以下结构:复制结构一个字节的缓冲区内

struct sample { 
    uint8_t four; 
    bool b; 
    uint8_t two; 
}; 

为了发送一个UDP包,我需要将这些值打包到一个单字节:

| 0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 
+---+---+---+---+---+---+---+---+ 
|  four  | 0 | b | two | 
+---------------+---+---+-------+ 

什么复制此字节中的结构值的最佳方法是什么?我在做这件事之前检查了前提条件,因此在将uint8_t值复制到更少的空间时不会丢失任何数据。

回答

5

我只想用一个函数:

uint8_t pack(const sample &s) 
{ 
    return (s.four & 0xF) | (s.b << 5) | ((s.two & 3) << 6); 
} 

,你说,数据范围检查,你可以简化到:

return s.four | (s.b << 5) | (s.two << 6); 
2

因为你的代码是不可移植的反正,你可能也仅仅使用位字段位置:

struct sample { 
    uint8_t four:4; 
    bool empty:1; 
    bool b:1; 
    uint8_t two:2; 
}; 

我不是位字段的球迷,但他们似乎是适合你的情况。

+1

在'b'之前不应该'empty'吗? – Slava

+0

@Slava,当然。固定,thx。 – SergeyA

+1

为什么不能携带? – Jepessen

0

你的位顺序以显示独特的...办法。通常当我们用二进制表示值时,低位显示在右边。只要你打包和解包数据,你可以选择你的位次序。不过请注意网络订单与系统订单。虽然每个平台上的字节中的位顺序相同,但字节顺序中的字可以更改。

您必须知道您的应用程序以确定打包/拆包是否值得您付出努力。在每一方都有更多的计算,并且取决于UDP数据包之间的间隔和每个UDP数据包中打包的数据量,这可能不值得。如果你只是想为移动应用程序保存数据,那么谢谢你:@)

我总是避免由于平台/编译器偏执狂而导致的布尔变换。可以使用类似s.b?32:0的东西来代替。

+0

我试图创建CIGI数据包,并且标准有很多数据包以这种方式构建... – Jepessen

+0

对不起,有点大脑失误。网络数据包总是以这种方式写入 –