Search code examples
c++boost-serialization

Boost serialization issue with text archive


I have a pretty simple class, that I want to serialize with boost::serialize.

class Entity {      
private:
    ObjectType objectType;
public:
    Entity(ObjectType t = tA) { objectType = t; }
public:
    ~Entity() {}
private:
      friend class boost::serialization::access;
  template <typename Archive>
  friend void boost::serialization::serialize(Archive& ar, Entity& o, const unsigned int version);
};

}

ObjectType is an enum:

typedef enum ObjectType {
 tA,
 tB,
 ...
 tZ
}

And the serialization function is the following:

template<class Archive>
void serialize(Archive & ar, Entity & o, const unsigned int version)
{
      ar & o.objectType;
}

Saving and loading are performed with the following functions:

void saveObject2File(const Entity &o, const char * filename) {
 std::ofstream ofs(filename);
 boost::archive::text_oarchive oa(ofs); 
 oa & o;
}

Entity * loadObjectFromFile(const char * filename) {
 std::ifstream ifs(filename);
 boost::archive::text_iarchive ia(ifs);
 Object * o;
 ia & o;
 return o;
}

When I serialize to a file, the following text is written into it, where the number 17 is the integer value stored in the objectType variable.

22 serialization::archive 10 0 0 17

However, when I read this file, the value 17 is received by the serialize method as the version parameter, and the objectType is assigned with a wrong value (o.objectType = -858993460).

If I manually change the class version BOOST_CLASS_VERSION(Entity, 111); before saving and loading, I get a runtime-exception. Writing works with the 111 version number, but reading the file fails.

Strangely enough, if I use xml archives, the problem does not occur. The problem is the same if I opt to serialize an integer instead of the enum. It seems as if the text_iarchive is looking for (and reading) an extra parameter, which is not provided by the text_oarchive, therefore 17 is read as the version number.

I am using Boost 1.55 and Visual Studio 2013.

Any help is welcome.


Solution

  • You made a standard mistake here: you serialize an OBJECT (of type Entity) but you try to deserialize A POINTER. You should make it consistent (OBJECT-OBJECT or POINTER-POINTER).

    It also seems you did not tell the whole story and your class Entity is a base of some class hierarchy. In this case you likely should use serialization of POINTERs; besides you will need methods described here: Boost Serialization: pointer conainer to <BASE> contains various of DERIVED objects