带有柔性阵列构件的包装结构的便携式替代方案

Portable alternative for packed structures with a flexible array member

本文关键字:便携式 结构 方案 包装 阵列 构件      更新时间:2023-10-16

>假设我们正在编写一个使用 UDP 套接字的C++网络应用程序。我们需要传递一个不那么小的数据包,所以我们使用了这种结构,确保字节顺序是网络顺序:

struct [[gnu::packed]] datagram {
    uint64_t timestamp;
    uint8_t type;
    uint32_t temperatures[60]; // whatever, just an example
    uint8_t raw_data[];
};

我们使用的是GNU GCC,所以我们利用了非标准的C++特性,如

  • 灵活的阵列成员
  • 包装结构

我们需要一个打包的结构,因为我们不希望中间有填充,因为这可能依赖于架构,并且我们的网络程序可以在不同的架构上运行。

然后,一年后,我们可能会发现我们需要支持一个不支持这些的非 GCC 编译器。

是否可以在标准C++中执行此操作?

当然,我知道我们可以简单地使用uint8_t buffer[SOME_SIZE]和memcpy数据报的每个部分,但这听起来像是创建可怕,非常丑陋的代码的好方法。

[[gnu::packed]]是在任意体系结构之间进行序列化的糟糕方法。 那里仍然有大端机器。

执行此操作的正确方法是根据八位字节定义序列化格式,然后在八位字节流(传入或传出 UDP 套接字(和排列良好的结构之间进行转换。

有许多库使这变得简单明了。 我们在工作中使用protobuf;以前的雇主有一个自制的解决方案。 (请注意,对此类库的建议请求对于堆栈溢出来说是明确的题外话。