Cro*_*rog 2 c c++ int protocol-buffers flatbuffers
我们以高数据速率通过 UART 串行发送数据,因此数据大小很重要。对于我们的数据,最优化的格式是 Int24,它可以简化为 C/C++ 下的 C 位域结构(GCC 编译器)以实现完美优化:
#pragma pack(push, 1)
struct Int24
{
int32_t value : 24;
};
#pragma pack(pop)
typedef std::array<Int24,32> ArrayOfInt24;
Run Code Online (Sandbox Code Playgroud)
这些数据与其他数据打包在一起,并在设备和云基础设施之间共享。基本上,我们需要在不同架构和编程语言的设备之间发送二进制序列化。我们希望使用基于模式的二进制序列化,例如 ProtoBuffers 或 FlatBuffers,以避免客户端代码需要自行处理二进制补码符号位处理的相应位移和恢复。即在非 C 语言中读取 24 位值需要以下内容:
bool isSigned = (_b2 & (byte)0x80) != 0; // Sign extend negative quantities
int32_t value = _b0 | (_b1 << 8) | (_b2 << 16) | (isSigned ? 0xFF : 0x00) << 24;
Run Code Online (Sandbox Code Playgroud)
如果尚不存在哪个(如果有)现有的二进制序列化库可以轻松修改以扩展对此的支持,因为我们愿意在这方面添加到任何开源项目中。
根据不同的情况,您可能想查看 ASN.1 和未对齐的打包编码规则 (uPER)。这是一种广泛用于电话的二进制序列化,可轻松减少传输的位数。工具可用于 C、C++、C#、Java、Python(我认为它们涵盖了 uPER)。一个好的起点是有用的旧技术。
您可能选择使用它的原因之一是 uPER 最终可能比其他任何东西都做得更好。其他好处是限制(关于值和数组大小)。您可以在您的架构中表达这些,生成的代码将根据它们检查数据。这可以对项目产生真正的影响 - 自动清理传入数据是抵御攻击的好方法 - 而 GPB 不会这样做。
不使用它的原因是最好的工具是商业的,而且价格昂贵。虽然有一些开源工具非常好,但不一定实现整个 ASN.1 标准(这是很大的)。这也是一个学习曲线,尽管(在基本层面上)与 Google Protocol Buffers 并没有太大的不同。事实上,在谷歌宣布 GPB 的大会上,有人问“为什么不使用 ASN.1?”。Google 的团队没有听说过它。有点讽刺的是,一家搜索公司没有在网上搜索二进制序列化技术,而是直接发明了他们自己的......