C++ C++;序列化:如何在一个程序中归档一个对象并在另一个程序中恢复它?

C++ C++;序列化:如何在一个程序中归档一个对象并在另一个程序中恢复它?,c++,serialization,boost,C++,Serialization,Boost,我正在使用Boost序列化来保存和加载游戏的整体状态,并在外部存储地图和生物数据 我有两个节目。第一个运行游戏本身,根据保存在外部文件中的数据根据需要创建新对象。它还生成自己状态的保存文件。到目前为止,所有这些都有效 第二,我是作为一名专门的编辑而创作的。我想用它来创建和操纵游戏程序使用的上述文件 因此,我在所有需要外部文件的类的第二个程序中制作了镜像,但具有不同的编辑功能。数据库中的所有数据 void serialize(AreaArchive & aar, const unsigne

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

我有两个节目。第一个运行游戏本身,根据保存在外部文件中的数据根据需要创建新对象。它还生成自己状态的保存文件。到目前为止,所有这些都有效

第二,我是作为一名专门的编辑而创作的。我想用它来创建和操纵游戏程序使用的上述文件

因此,我在所有需要外部文件的类的第二个程序中制作了镜像,但具有不同的编辑功能。数据库中的所有数据

void serialize(AreaArchive & aar, const unsigned int version)
{...}
两个程序的类的一部分是相同的

我使用此选项创建文件:

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;
}
areaGen.向后推(新区域(“area1”);
std::字符串文件名;
对于(std::vector::iterator it=areaGen.begin();it!=areaGen.end();++it)
{
fileName=(*it)->name+“.areabase”;
std::流区域文件(文件名);
boost::archive::text\u oarchive outArchive(区域文件);

outArchive一个关于如何打印异常消息的非常简单的示例:

try
{
    inArchive >> *target;
}
catch (std::exception& e)
{
    std::cerr << "Exception: " << e.what() << '\n';
}
试试看
{
Inachive>>*目标;
}
捕获(标准::异常&e)
{

一般来说,Boost序列化不支持这种行为

对于非常简单的(POD,当然不是虚拟类型)你将能够摆脱事物。例如,我在过去已经序列化了<代码> map ,并将其反序列化为“<代码>扁平地图> /代码>,对于琐碎的<代码> K<代码>代码>代码> V<代码>。但是,这些都不是用于库的用途,而应该考虑未指定的行为。因此,除非您已经为您验证了ALL代码路径。self确保您所做的工作将起作用,为什么不使用Boost序列化

现在,这里有一个不应该起作用的小例子:

这些类型将是不相关的,并且将从Boost序列化中检查RTTI

如何解决这个问题? 你可以

  • 将可序列化类型移动到共享(静态)库中,并使用两个程序中完全相同的代码。问题消失了,因为类型信息是共享的
  • 使用自定义二进制序列化
  • 改为使用共享内存/内存映射文件(尽管这不是一件小事,所以只有在您有信心可以完成上述任务时才这样做)
重要事实上,Boost序列化二进制存档不是非常可移植的!您应该查看[EOS portable archives](通常,Boost序列化不支持这种行为)

对于非常简单的(POD,当然不是虚拟类型),您将能够处理一些事情。例如,我过去序列化了
映射
,并将其反序列化为
平面映射
)但是,这些都不是对图书馆的预期用途,您应该考虑未指定的行为。因此,除非您已经为自己确认了ALL代码路径,以确保您所做的工作将是有效的,并且为什么不使用升序序列化变得聪明。 现在,这里有一个不应该起作用的小例子:

这些类型将是不相关的,并且将从Boost序列化中检查RTTI

如何解决这个问题? 你可以

  • 将可序列化类型移动到共享(静态)库中,并使用两个程序中完全相同的代码。问题消失了,因为类型信息是共享的
  • 使用自定义二进制序列化
  • 改为使用共享内存/内存映射文件(尽管这不是一件小事,所以只有在您有信心可以完成上述任务时才这样做)
重要事实上,二进制存档不是非常可移植的!如果要在不同的机器上共享存档,请查看。
)如果您想在不同的机器等之间共享归档文件,您会遇到什么异常?您是否尝试捕获它并打印出它的信息?我不知道异常是如何工作的或曾经使用过它们,但请尝试{inArchive>>*target;}catch(std::exception){throw;}导致输出“在抛出'boost::archive::archive_exception'what()的实例后调用terminate”:input stream Error如果您看到,例如,您将注意到一个函数,该函数将为您提供一个可以打印的字符串。如果您对异常一无所知,这可能是了解异常的好时机。谢谢。我不确定用什么对象调用std::exception::what(),但是,如果我错了,请更正-似乎暗示输出是what()步骤由boost负责。不管怎样,“input stream error”不是已经输出的字符串吗?我怀疑存在错误,因为我试图将错误类型的对象塞入*target。如何创建有效的对象?好的,谢谢,但输出行仍然是“Exception:input stream error”一字不差,我不认为还有更多。
try
{
    inArchive >> *target;
}
catch (std::exception& e)
{
    std::cerr << "Exception: " << e.what() << '\n';
}
 struct A { 
     int x;
     virtual void display() const; {}
 };

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

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