在字节缓冲区中复制结构
Posted
技术标签:
【中文标题】在字节缓冲区中复制结构【英文标题】:Copy a struct inside a byte buffer 【发布时间】:2016-07-28 19:26:41 【问题描述】:我有以下结构:
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
值复制到更小的空间时不会丢失任何数据。
【问题讨论】:
【参考方案1】:我只想使用一个函数:
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;
;
我不喜欢位字段,但它们似乎适用于您的情况。
【讨论】:
不应该empty
出现在b
之前吗?
为什么不便携?
因为你要对 uint8_t 进行实体序列化,而那是不可移植的。【参考方案3】:
您的位顺序以...独特的方式显示。通常当我们用二进制表示值时,低位显示在右侧。只要您在打包和解包数据,您就可以选择您的位顺序。不过要注意网络顺序与系统顺序。虽然每个平台的字节内位顺序都是相同的,但字内字节顺序可以改变。
您必须了解您的应用程序才能确定打包/拆包是否值得。在每一侧进行更多的计算,并且取决于 UDP 数据包之间的间隔以及每个 UDP 数据包中包含多少数据,这可能不值得。如果您只是想为蜂窝应用程序保存数据,那么,谢谢 :@)
由于平台/编译器偏执,我总是避免转换布尔值。可以改用 s.b?32:0 之类的东西。
【讨论】:
我正在尝试创建 CIGI 数据包,标准有很多以这种方式构建的数据包... 抱歉,有点脑残。网络数据包总是这样写的以上是关于在字节缓冲区中复制结构的主要内容,如果未能解决你的问题,请参考以下文章
无法将固定大小的字节数组从结构复制到 C# 结构中的另一个数组