我似乎无法使boost :: serialization运行良好。在包含类和归档标题之后,我将类.cpp文件与BOOST_CLASS_EXPORT_GUID
宏一起使用了,但我仍然得到unregistered_class
例外。
我环顾四周,似乎无论我能找到的是1.过时,处理旧版本的库,或2.仅适用于简单的单文件解决方案,其中所有可序列化的类都定义为在另一个之后。我找不到任何帮助。
我目前的解决方案包括一个项目,编译成静态库,包含基本可存档类的核心功能,以及另一个最终将充实到更具体的逻辑层的测试项目。让一切与boost :: serialization一起工作是一场噩梦。我差点想自己写。
无论如何,引发异常的问题是在标题中定义的,看起来像这样:
#include <boost/serialization/assume_abstract.hpp>
#include <boost/serialization/serialization.hpp>
// Other includes...
namespace GameCore { class Component; }
// Forward declare some boost::serialization functions that appear at the bottom.
// ...
BOOST_SERIALIZATION_ASSUME_ABSTRACT(GameCore::Component);
namespace GameCore
{
// Some forward declares..
//////////////////////////////////////////////////////////////////////////
// Base component type.
//////////////////////////////////////////////////////////////////////////
class Component : public Updatable, public Object
{
friend class boost::serialization::access;
protected:
template <typename Archive>
friend void boost::serialization::serialize(Archive& archive, Component& object, const unsigned int version);
template <typename Archive> friend void boost::serialization::load_construct_data(Archive& archive, Component* t, const unsigned int version);
template <typename Archive> friend void boost::serialization::save_construct_data(Archive& archive, const Component* t, const unsigned int version);
public:
Component(GameObject& owner);
virtual ~Component() = 0;
// Irrelevant stuff..
GameObject& gameObject;
Transform* transform;
};
}
// The component includes have to be placed here because it would otherwise create a cyclic inclusion when trying to compile the
// individual component classes, say, Transform, which would end up including itself.
#include "Transform.h"
namespace boost
{
namespace serialization
{
template<class Archive>
inline void save_construct_data(Archive& archive, const GameCore::Component* t, const unsigned int version)
{
archive << t->gameObject;
}
template<class Archive>
inline void load_construct_data(Archive& archive, GameCore::Component* t, const unsigned int version)
{
// Retrieve data from archive required to construct new instance.
GameCore::GameObject owner;
archive >> owner;
// Invoke inplace constructor to initialize instance of class.
::new(t)GameCore::Component(owner);
}
//////////////////////////////////////////////////////////////////////////
// Serialization function for save/load.
//////////////////////////////////////////////////////////////////////////
template <typename Archive>
void serialize(Archive& archive, GameCore::Component& t, const unsigned int version)
{
archive & boost::serialization::base_object<GameCore::Object>(t);
archive & boost::serialization::base_object<GameCore::Updatable>(t);
archive & t.gameObject;
archive & t.transform;
}
}
}
这是一个头文件。很抱歉。它的.cpp文件如下所示:
#include "Component.h"
#include <boost/serialization/export.hpp>
#include <boost/archive/text_iarchive.hpp>
#include <boost/archive/text_oarchive.hpp>
// Other includes...
BOOST_CLASS_EXPORT_GUID(GameCore::Component, "GameCore::Component");
// Class method definitions here.
当我尝试从Component
归档派生的实例对象时引发异常,std::ofstream outputFile(fileName);
boost::archive::text_oarchive outputArchive(outputFile);
outputArchive << objects;
本身是一个抽象类。我通过在不同经理类中定义的简单方法进行归档:
objects
其中std::list
是Object
的{{1}}。 Object
是所有内容(包括Component
)派生的基类。
如果这听起来很复杂,我道歉,但只有三层继承,我相信在序列化的想法悄悄进入之前我有一个整洁有效的架构。
如果你能帮助我摆脱不合理的unregistered_class
例外情况,我会为你的灵魂点上蜡烛!
更新:有趣的是,Component
的所有派生类都没有引发异常。
答案 0 :(得分:6)
在我的神经元寻找答案后,我偶然发现了文档中的这一行:
静态库和序列化
数据类型序列化的代码可以保存在库中 它可以用于其余的类型实现。这很好用,而且 可以节省大量的编译时间。只编译序列化 库中的定义。显式实例化序列化代码 对于您打算在库中使用的所有归档类。出口 类型,只在标题中使用BOOST_CLASS_EXPORT_KEY。对于导出类型, 只在编译的定义中使用BOOST_CLASS_EXPORT_IMPLEMENT 图书馆。对于任何特定类型,应该只有一个文件 包含该类型的BOOST_CLASS_EXPORT_IMPLEMENT。这确保了 程序中只存在一个序列化代码副本。它 避免浪费空间和不同版本的可能性 同一程序中的序列化代码。包含 多个文件中的BOOST_CLASS_EXPORT_IMPLEMENT可能会导致a 由于重复的符号或投掷运行时而无法链接 异常。
将BOOST_CLASS_EXPORT
拆分为BOOST_CLASS_EXPORT_KEY
和BOOST_CLASS_EXPORT_IMPLEMENT
似乎有效。