c++ - 通过网络传递 std::variant 是否安全,跨平台
问题描述
std::variant 是联合的替代品。
但是联合可以通过网络安全地在另一个平台(不同的编译器或架构)中接收。std::variant 可以这样做吗?
比如我有两台机器A和B。A是windows,MSVC 19.4。B 是 Linux、gcc(或其他编译器,例如 MSVC 17)。我在A(或B)下编译代码:
std::variant<int, double> v = 1; // holds int.
f.write(&v, sizeof(v));
B 可以使用同一文件中的以下代码读取正确的值吗?
std::variant<int, double> v;
f.read(&v, sizeof(v));
如果 std::variant 不能安全地通过网络。有没有图书馆提供?提升::变体?或者也许创建一个像 std::variant 一样的自定义实现?
解决方案
通常,C++ 中的联合、变体或许多其他类型都不能被内存转储到文件中然后安全读取。
当跨多个平台(即硬件)传输数据时,很多事情都会使传输不安全:
- 字节序(今天的大多数机器,如 x86 都是小字节序)
- 大小(
int
例如,您所指的类型在一个平台上可以是 4 个字节,在另一个平台上可以是 8 个字节。) - 一个字节有多少位(
CHAR_BIT
通常是 8,这仅适用于少数神秘平台) - 使用的浮点实现。(现在大多数硬件都使用IEEE-754,但 C++ 标准不需要这个)
正因为如此,跨平台传输数据的唯一安全方法是使用标准化的中间数据格式,通常称为序列化。许多图书馆可以帮助您解决这个问题。一些要研究的是
如果问题更针对 的内存布局std::variant
,则与std::variant
任何其他std
容器一样:内存布局是实现定义的。(这里的实现是指使用的标准库实现)。例如,一些标准库在 中进行了小字符串优化std::string
,它可以包含小字符串(例如,少于 32 个字符)而无需堆分配。有些没有。因此,对于同一类型,您的内存布局会有很大的不同。
因此,要么保证发送方和接收方都具有相同的硬件和标准库实现,要么使用序列化库来确保与发送的数据相同。
推荐阅读
- python - 根据第一个数据框中的数据填充另一个数据框中的值
- c++ - 错误:无法获取“void”类型的右值的地址。两个具有相同工作流程的类,但一个会引发错误
- video - 不要使用显示 gstreamer aarch 64 linux
- c# - 从字典值到 IEnumerable 的连接列表
- keras - 具有 KL Divergence 层的变分自编码器多输出损失函数
- css - 如何拉伸子元素的高度以填充除文本之外的父元素?
- c++11 - shared_ptr
不编译 - php - 在 WooCommerce 变体旁边显示缺货
- node.js - 如何在typeorm中以异步等待发布请求
- javascript - node-js 和 Mongodb 中的时间间隔系列数据库处理