Luciano Lorenti
Luciano Lorenti

Reputation: 601

Multiple libraries and boost serialization

I have a problem with the following situation: I have a Class, let's say Base in a dynamic library. Base can be serialized. I have another class, Derived, in a different dynamic library wich is derived from Base that can be serialized too. When I serialize an instance of Derived stored in a Base* variable in a program linked with libBase and libDerived, I can't make boost see Derived. i.e.

The file generated has the following content

22 serialization::archive 10 0 1 0
0 10 Base Class

I understand that the serialize function of Derived is never invoked

What am I missing?

Base.h

#ifndef BASE_H
#define BASE_H
#include <string>
#include <boost/serialization/export.hpp>
#include <boost/serialization/access.hpp>
using namespace std;
class Base {
public:
  Base();  
private:
  string _str;
  friend class boost::serialization::access;
  template<class Archive>
  void serialize(Archive & ar, const unsigned int version);   
};
BOOST_CLASS_EXPORT_KEY(Base)
#endif

Base.cpp

#include "base.h"
Base::Base() : _str("Base Class") {}
template<class Archive>
void Base::serialize(Archive & ar, const unsigned int version){
   ar & _str;
}

#include <boost/archive/text_oarchive.hpp>
#include <boost/archive/text_iarchive.hpp>
template void Base::serialize(boost::archive::text_oarchive & ar, const unsigned int version);
template void Base::serialize(boost::archive::text_iarchive & ar, const unsigned int version);
BOOST_CLASS_EXPORT_IMPLEMENT(Base)

Derived.h

#ifndef DERIVED_H
#define DERIVED_H
#include <string>
#include "base.h"
#include <boost/serialization/export.hpp>
#include <boost/serialization/access.hpp>
using namespace std;
class Derived : public Base {
public:
  Derived();  
private:
  string _str;
  friend class boost::serialization::access;
  template<class Archive>
  void serialize(Archive & ar, const unsigned int version);
};
BOOST_CLASS_EXPORT_KEY(Derived)
#endif

Derived.cpp

#include "derived.h"
#include <boost/serialization/base_object.hpp>
Derived::Derived() : Base(), _str("derived") { }

template<class Archive>
void Derived::serialize(Archive & ar, const unsigned int version){
   ar & boost::serialization::base_object<Base>(*this);
   ar & _str;
}

#include <boost/archive/text_oarchive.hpp>
#include <boost/archive/text_iarchive.hpp>
template void Derived::serialize(boost::archive::text_oarchive & ar, const unsigned int     version);
template void Derived::serialize(boost::archive::text_iarchive & ar, const unsigned int version);
BOOST_SERIALIZATION_MWERKS_BASE_AND_DERIVED(Base, Derived)
BOOST_CLASS_EXPORT_IMPLEMENT(Derived)

main.cpp

#include "derived.h"
#include <iostream>
#include <fstream>
#include <boost/archive/text_oarchive.hpp>
int main()
{
    Base * b = new Derived();
    std::ofstream ofs("test.txt");
    boost::archive::text_oarchive oa(ofs);
    oa << b;
    ofs.close();
 }

compile.sh

g++ -g -c -Wall -fPIC base.cpp -o base.o
g++ -shared -Wl,-soname,libbase.so -o libbase.so base.o -lc
g++ -g -c -Wall -fPIC derived.cpp -o derived.o
g++ -shared -Wl,-soname,libderived.so -o libderived.so derived.o -lc
g++ main.cpp -lbase -lderived -o main -L . -lboost_serialization

Upvotes: 1

Views: 353

Answers (1)

sehe
sehe

Reputation: 393134

Your type needs to support RTTI.

In order for this to be true, it needs to have a vtable. The most common member to make virtual is the destructor:

virtual ~Base() = default;

Now it results in

22 serialization::archive 10 1 1 0
0 1 0
1 10 Base Class 13 derived_value

If you can't afford to use RTTI, the library provides an alternative: http://www.boost.org/doc/libs/1_55_0/libs/serialization/doc/traits.html#typeinfo

Upvotes: 2

Related Questions