I am looking to serialize a polymorphed class from its associated interface.
Here is what I have found this question, which seems to do what I need to: How to create a interface for serialization in Boost Serialization?
However the serialization is done from the class itself and not the interface. What I have got so far:
INetworkMessage.hpp
using PolyArchive = boost::variant<
boost::archive::polymorphic_oarchive &,
boost::archive::polymorphic_iarchive&>;
class INetworkMessage {
public:
INetworkMessage() = default;
virtual ~INetworkMessage() = default;
virtual void serialize(PolyArchive ar, unsigned int version) = 0;
};
namespace visitor {
template <typename F> struct wrap_visitor : boost::static_visitor<>
{
wrap_visitor(F const& f) : f_(f) { }
wrap_visitor(F&& f) : f_(std::move(f)) { }
template<typename... T> void operator()(T&&... t) const
{
f_(std::forward<T>(t)...);
}
private:
F f_;
};
template <typename F>
wrap_visitor<F> make_visitor(F&& f)
{
return std::forward<F>(f);
}
}
BOOST_SERIALIZATION_ASSUME_ABSTRACT(INetworkMessage)
NetworkMessage.hpp
class NetworkMessage : public INetworkMessage {
public:
struct Header
{
enum MessageType
{
TYPE_LOGIN,
TYPE_LOGOUT,
TYPE_CONTROL,
TYPE_VOICE
};
unsigned long long int to;
unsigned long long int from;
enum MessageType type;
size_t size;
};
NetworkMessage();
NetworkMessage(const struct NetworkMessage::Header &header);
virtual ~NetworkMessage() = 0;
struct NetworkMessage::Header &getHeader();
virtual void serialize(PolyArchive ar, unsigned int) = 0;
private:
struct Header header;
};
BOOST_SERIALIZATION_ASSUME_ABSTRACT(NetworkMessage)
NetworkMessageLogin.hpp
class NetworkMessageLogin : public NetworkMessage {
public:
NetworkMessageLogin();
NetworkMessageLogin(const struct NetworkMessage::Header &header);
~NetworkMessageLogin();
void setId(unsigned long long int id) noexcept;
unsigned long long int getId() const noexcept;
void setName(const std::string &name) noexcept;
const std::string &getName() const noexcept;
virtual void serialize(PolyArchive ar, unsigned int) override;
protected:
unsigned long long int id;
std::string name;
};
And here is what I'd like to be able to do:
struct NetworkMessage::Header header = { 0, 1, NetworkMessage::Header::TYPE_LOGIN, 4 };
NetworkMessageLogin msg(header);
msg.setId(1245);
msg.setName("Test");
INetworkMessage *interface = new NetworkMessageLogin(msg);
std::stringstream ss;
boost::archive::polymorphic_text_oarchive oa(ss);
oa << interface;
std::cout << "Serial: " << ss.str() << std::endl;
With this attempt I get an exception what(): unregistered class - derived class not registered or exported
.
I've tried using the CLASS_BOOST_EXPORT
on NetworkMessageLogin
, but without success, I just had a bunch of errors.
How can I achieve serialization from the interface of a class implementing my serialization method ?