I'm trying to send an object that is an instance of a derived class through a boost::asio socket using UDP.
Let's say the child class is PacketA with the base class being the Packet.
I'm able to serialize PacketA in the client program but whenever I try to deserialize it in the server it throws the following error:
terminate called after throwing an instance of 'boost::archive::archive_exception' what(): unregistered class
To try and fix this I added the macros BOOST_CLASS_EXPORT_IMPLEMENT
in the PacketA cpp file and the BOOST_CLASS_EXPORT_KEY
in the header file while in the Packet class I didn't add any macro, but it still doesn't work. I added these macros because of this section of the boost docs.
I also tried to use the register_type()
function to register the child classes but I wasn't successful either and the solutions seems to be worse than the macros.
Is there any obvious mistake that I'm making or am I using the API wrongly?
Code:
Deserialize:
udp::endpoint senderEndPoint;
char buffer[MAX_PACKET_SIZE] = {"\n"};
int bytes = socket->receive_from(boost::asio::buffer(buffer, MAX_PACKET_SIZE), senderEndPoint, 0,error);
std::stringstream stringStream(buffer);
boost::archive::text_iarchive ia{stringStream};
Packet *packet; //<-It throws the exception in this line but If I switch this pointer to
//PacketA it works fine but the idea is to deserialize multiple child
//packets that came from the sockets.
ia & packet;
packet->bytes = 0;
packet->senderEndPoint = senderEndPoint;
Packet.cpp:
#include <boost/archive/text_iarchive.hpp>
#include <boost/archive/text_oarchive.hpp>
#include "Packet.hpp"
template<class Archive>
void Packet::serialize(Archive &ar, unsigned int version) {
//I didnt add any code in here since I don't really need to serialize any information just the child packets
}
template void Packet::serialize(boost::archive::text_iarchive &arch, const unsigned int version);
template void Packet::serialize(boost::archive::text_oarchive &arch, const unsigned int version);
Packet.hpp:
#include <boost/serialization/access.hpp>
#include <boost/serialization/export.hpp>
#include <boost/asio/ip/udp.hpp>
using PacketType = std::string;
class Packet {
public:
friend class boost::serialization::access;
/*Some variables and functions from packet*/
template<class Archive>
void serialize(Archive &, unsigned int version);
};
PacketA.cpp:
#include "PacketA.hpp"
#include <boost/archive/text_oarchive.hpp>
#include <boost/serialization/base_object.hpp>
/*Some other functions*/
template<class Archive>
void PacketA::serialize(Archive &ar, unsigned int version) {
ar & boost::serialization::base_object<Packet>(*this);
ar & boost::serialization::make_nvp("PacketType", packetType);
}
BOOST_CLASS_EXPORT_IMPLEMENT(PacketA)
PacketA.hpp:
#include <boost/serialization/export.hpp>
#include "../Packet.hpp"
class PacketA : public Packet {
public:
PacketType packetType = "PacketA";
friend class boost::serialization::access;
/*Some functions*/
template<class Archive>
void serialize(Archive &ar, unsigned int version);
};
BOOST_CLASS_EXPORT_KEY(PacketA)
To serialize all the packets I'm using this function:
std::stringstream foo::serializePacket(Packet *packet) { //<-Here the *packet could be any
//packet child
std::stringstream ss;
boost::archive::text_oarchive oa{ss};
oa & packet;
return ss;
}