C ++ Boost :: serialization:如何在一个程序中归档对象,然后在另一个程序中恢复它? [英] C++ Boost::serialization : How do I archive an object in one program and restore it in another?

查看:74
本文介绍了C ++ Boost :: serialization:如何在一个程序中归档对象,然后在另一个程序中恢复它?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在使用Boost序列化来保存和加载游戏的整体状态,以及在外部存储地图和生物数据.

I'm using Boost Serialization for saving and loading my game's overall state as well as storing map and creature data externally.

我有两个程序.首先运行游戏本身,根据外部文件中保存的数据根据​​需要创建新对象.它还会生成自己状态的保存文件.到目前为止,所有这些都有效.

I have two programs. The first runs the game itself, creating new objects as necessary based on the data saved in the external files. It also produces savefiles of its own state. These all work so far.

第二,我正在创建一个专用的编辑器.我想用它来创建和操作要由游戏程序使用的文件.

The second, I am creating as a dedicated editor. I want to use it to create and manipulate said files to be used by the game program.

因此,我在所有需要外部文件的类的第二个程序中制作了镜像,但出于编辑目的,它们具有不同的功能.

So I made mirror images in the second program of all the classes that require external files, but with different functions for the purposes of editing. All the data in the

void serialize(AreaArchive & aar, const unsigned int version)
{...}

任何一个程序的类的一部分都是相同的.

part of either program's class is the same.

我用它来创建文件:

areaGen.push_back(new Area("area1"));

std::string fileName;

for(std::vector<Area*>::iterator it = areaGen.begin(); it != areaGen.end(); ++it)
{
    fileName = (*it)->name + ".areabase";
    std::ofstream areafile(fileName);

    boost::archive::text_oarchive outArchive(areafile);
    outArchive << *it;
}

假设文件"area1.areabase"是完全AFAIK生成的.我将其移到我的第一个程序的目录中,以如下方式执行功能:

The file, let's say "area1.areabase" is produced perfectly AFAIK. I move it to the directory of my first program, execute the function as

bool LoadAreaState(std::string areaName, Area *target, bool baseState)
{
std::cout << "Debug: entered area loading function..." << std::endl;

std::string fileName;
if(baseState)
    fileName = areaName + ".areabase";
else
    fileName = areaName + ".areafile";

std::ifstream areafile(fileName);

...

std::cout << "Debug: file opened sucessfully..." << std::endl;

boost::archive::text_iarchive inArchive(areafile);

std::cout << "Debug: inarchive to target..." << std::endl;

inArchive >> *target; // The step at which it fails - Terminate by boost::serialization's exception

std::cout << "Debug: target Area object restored..." << std::endl;

return true;
}

当然是行不通的.无论如何,第一个程序和第二个程序中的类的成员对象不能相同.可以吗但是序列化块包含完全相同的类型数据.

And of course it doesn't work. The member object of the class in the first and second programs couldn't be the same anyway. Could it? But the serialize blocks contain the exact same type data.

我希望这个例子能表达我想要做的事情.但是有办法使它起作用吗?

I hope this example expresses what I'm trying to do. But is there a way I can make it work?

非常感谢.

推荐答案

通常,Boost序列化不支持此行为.

In general, this is not supported behaviour by Boost Serialization.

对于严格的琐事(POD,当然不是虚拟类型),您将可以放手一搏.例如.我过去曾序列化一个 map< K,V> 并将其反序列化为一个 flat_map< K,V> ),以用于普通的 K V .但是,这些都不打算用于库,您应该考虑未指定的行为.因此,除非您已经为自己验证了alll代码路径,以确保您正在执行的操作以及为什么执行,否则不要通过Boost Serialization变得聪明.

For strictly trivial (POD, certainly not virtual types) you will be able to get away with things. E.g. I've in the past serialized a map<K,V> and deserialized it as a flat_map<K,V>), for trivial K and V. However, none of this is intended use for the library and you should consider the behaviour unspecified. So, unless you have verified alll code paths for yourself to be sure that what you are doing will work, and why, don't get smart with Boost Serialization.

现在,这是一个简单的示例,应该起作用:

Now, here's a trivial example that should not work:

 struct A { 
     int x;
     virtual void display() const; {}
 };

 struct B {
     int x
     virtual void display() const; {}
 };

类型将不相关,RTTI将通过Boost序列化进行检查.

The types will be unrelated, and the RTTI will be checked from Boost Serialization.

您可以

  • 将可序列化类型移动到共享(静态)库中,并使用两个程序中完全相同的代码.问题消失了,因为类型信息是共享的
  • 使用自定义二进制序列化
  • 改为使用共享的内存/内存映射文件(尽管这并非易事,所以只有在确信自己可以执行上述操作的情况下,才这样做)

重要 Boost Serialization二进制归档文件不是 ,实际上非常易于移植!您应该查看[EOS Portable Archives](通常,Boost序列化不支持此行为.

IMPORTANT Boost Serialization binary archives are not, in fact, very portable! You should look at [EOS Portable Archives](In general, this is not supported behaviour by Boost Serialization.

对于严格的琐事(POD,当然不是虚拟类型),您将可以放手一搏.例如.过去,我已经序列化了 map< K,V> 并将其反序列化为 flat_map< K,V> ).但是,这些都不打算用于库,您应该考虑未指定的行为.因此,除非您已经为自己验证了alll代码路径,以确保您正在执行的操作以及为什么执行,否则不要通过Boost Serialization变得聪明.

For strictly trivial (POD, certainly not virtual types) you will be able to get away with things. E.g. I've in the past serialized a map<K,V> and deserialized it as a flat_map<K,V>). However, none of this is intended use for the library and you should consider the behaviour unspecified. So, unless you have verified alll code paths for yourself to be sure that what you are doing will work, and why, don't get smart with Boost Serialization.

现在,这是一个简单的示例,应该起作用:

Now, here's a trivial example that should not work:

 struct A { 
     int x;
     virtual void display() const; {}
 };

 struct B {
     int x
     virtual void display() const; {}
 };

类型将不相关,RTTI将通过Boost序列化进行检查.

The types will be unrelated, and the RTTI will be checked from Boost Serialization.

您可以

  • 将可序列化类型移动到共享(静态)库中,并使用两个程序中完全相同的代码.问题消失了,因为类型信息是共享的
  • 使用自定义二进制序列化
  • 改为使用共享的内存/内存映射文件(尽管这并非易事,所以只有在确信自己可以执行上述操作的情况下,才这样做)

重要 Boost Serialization二进制归档文件不是 ,实际上非常易于移植!如果要在不同的机器等之间共享档案,则应查看 EOS便携式档案.),如果您想在不同的机器之间共享档案等.

IMPORTANT Boost Serialization binary archives are not, in fact, very portable! You should look at EOS Portable Archives if you want to share the archives across different machines etc. ) if you want to share the archives across different machines etc.

这篇关于C ++ Boost :: serialization:如何在一个程序中归档对象,然后在另一个程序中恢复它?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆