I have a problem using RCF 2.2.0.0 with boost serialization for polymorphic types.
I want to change an instance of B passed via a reference of base class A. Using SF it works as expected:
Code: Select all
Calling the I_SetService Set() method.
B::SF_serialize
A::SF_serialize
B::SF_serialize
A::SF_serialize
B::set() 42
B::SF_serialize
A::SF_serialize
B::SF_serialize
A::SF_serialize
42 expected 42
Code: Select all
Calling the I_SetService Set() method.
A::boost_serialize saving
B::boost_serialize saving
A::boost_serialize loading
B::boost_serialize loading
B::set() 42
A::boost_serialize saving
A::boost_serialize loading
1 expected 42
Could you please give me a hint on how to make it work?
You can find my minimal example below.
Thanks in advance,
Sebastian
Code: Select all
#include <fstream>
#include <iostream>
#include "RCF/RCF.hpp"
#ifndef RCF_USE_BOOST_SERIALIZATION
#include "SF/Registry.hpp"
#include "SF/SerializeParent.hpp"
#endif
#include <boost/serialization/export.hpp>
#include <boost/serialization/nvp.hpp>
#include <boost/serialization/serialization.hpp>
class A
{
public:
virtual void set(int /*i*/)
{
throw std::runtime_error("A::set() is not expected to be called");
};
#ifndef RCF_USE_BOOST_SERIALIZATION
void serialize(SF::Archive& /*ar*/) { std::cout << "A::SF_serialize\n"; }
#endif
private:
friend class boost::serialization::access;
template <typename Archive>
void serialize(Archive& ar, unsigned int const /* version */)
{
std::cout << "A::boost_serialize "
<< (typename Archive::is_loading() ? "loading" : "saving") << '\n';
}
};
BOOST_CLASS_EXPORT(A)
class B : public A
{
public:
B() : s(1){};
void set(int i) override
{
std::cout << "B::set() " << i << "\n";
s = i;
}
int s;
#ifndef RCF_USE_BOOST_SERIALIZATION
void serialize(SF::Archive& ar)
{
std::cout << "B::SF_serialize\n";
SF::serializeParent<A>(ar, *this);
ar& s;
}
#endif
private:
friend class boost::serialization::access;
template <typename Archive>
void serialize(Archive& ar, unsigned int const /* version */)
{
using namespace boost::serialization;
ar& BOOST_SERIALIZATION_BASE_OBJECT_NVP(A);
ar& make_nvp("s", s);
std::cout << "B::boost_serialize "
<< (typename Archive::is_loading() ? "loading" : "saving") << '\n';
}
};
BOOST_CLASS_EXPORT(B)
RCF_BEGIN(I_SetService, "I_SetService")
RCF_METHOD_V2(void, Set, A&, int)
RCF_END(I_SetService)
class SetService
{
public:
void Set(A& a, int i) { a.set(i); }
};
int main()
{
try {
#ifndef RCF_USE_BOOST_SERIALIZATION
SF::registerType<B>("B");
SF::registerBaseAndDerived<A, B>();
#endif
RCF::RcfInitDeinit rcfInit;
RCF::RcfServer server(RCF::TcpEndpoint("127.0.0.1", 50001));
SetService printService;
server.bind<I_SetService>(printService);
server.start();
RcfClient<I_SetService> client(RCF::TcpEndpoint("127.0.0.1", 50001));
B b = B();
A& a = b;
int const value = 42;
std::cout << "Calling the I_SetService Set() method." << std::endl;
client.Set(a, value);
std::cout << b.s << " expected " << value << '\n';
} catch (const RCF::Exception& e) {
std::cout << "Error: " << e.what() << std::endl;
}
return 0;
}