c++ - 在为视频游戏实现基本的二进制序列化时,是否需要担心可移植性?

标签 c++ linux windows serialization

我正在编写一个简单的二进制序列化程序来为面向 Windows、Mac 和 Linux 64 位平台的 64 位视频游戏生成保存文件。为序列化选择的变量类型是:char、short、bool、unsigned int、int、float、可能是 double 也可能是 long int。我在 Visual Studio 上编译。序列化尽可能简单,没有检查,只是简单地写入二进制数据,然后以相同的顺序反序列化数据。游戏在整个游戏过程中非常频繁地将新数据保存到文件中,但数据仅在游戏开始前反序列化一次。

我不认为便携性是我需要担心的一个简单的游戏存档功能;但是,我一直在阅读与二进制序列化相关的许多可移植性问题(例如浮点表示、整数位宽的变化、字节顺序、对齐等),我对我对这个主题的理解不够自信,无法确定这些可移植性问题不会在这个项目中出现。也许有人会很友好地分享对以下假设的一些看法:

  1. 变量可以在一台机器上序列化为二进制文件 然后可以复制二进制文件并安全地反序列化 具有相同操作系统和 x86-64 CPU 的不同机器。
  2. 如果我假设所有运行游戏的机器都是运行 64 位操作系统的小端 x86-64 CPU, 我可以假设二进制文件可以在两者之间完全移植吗 操作系统也是?
  3. 如果我要扩展开发以支持 32 位版本的游戏(仍然假设目标上的 x86-64 CPU 架构 平台,但 32 位操作系统),并且 32 位操作系统最终用户决定 升级到 64 位操作系统,安装 64 位版本的游戏并 然后加载他们在 32 位上序列化的旧保存文件 运行 32 位版本游戏的 OS——那些变量类型可以吗 然后在 64 位平台上按顺序安全反序列化 它们在没有任何检查或测试的情况下被序列化 兼容性?

在任何这些情况下,在一台机器上保存并在另一台机器上加载是否可能会损坏数据?

非常感谢。

最佳答案

如果您使用诸如 ::std::uint32_t 之类的大小整数类型而不是诸如 unsigned long 之类的晦涩类型,那么您将大大减少整数大小的变化这可能发生在 32 位/64 位平台和不同的编译器之间。整数位宽在技术上可能会有所不同,但仅限于绝对不能被视为适合游戏的相当奇特的平台。浮点大小和表示也不应该是一个问题。

要确保正在读取/写入的数据结构的大小和对齐在跨平台时保持一致,您应该在代码中使用 static_assert

但是,如果您希望您的保存文件具有可移植性,则必须检查字节顺序。通常,您可能希望使用 native 字节顺序序列化数据,并在文件开头写入一些魔数(Magic Number)以指示其字节顺序(如 0x01020304)。然后,当你反序列化时,你首先检查这个魔法并选择 native 字节序反序列化器(更快)或翻转字节序反序列化器(更慢)。

关于c++ - 在为视频游戏实现基本的二进制序列化时,是否需要担心可移植性?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/44743758/

相关文章:

c++ - 无法读取客户端发送的所有消息

linux - 使用 grep 值创建文件

c++ - 在 c 程序开发期间删除注释的地方

c++ - 无法通过单词/或 12 个字符打印字符串

c++ - 在另一个库(SDL 和 Eclipse)之上构建一个新库

.net - 双击 Action 中使用了什么 shell 动词?

linux - 无法从 Windows 连接到 Redis Linux 服务器

windows - 与 Windows 容器汇合

c++ - std::function 与函数指针

linux - mxe 交叉编译 linux 到 windows vtk 示例