Reputation: 601
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
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