[serialization] seriazation from base pointer / Runtime Casting

is it possible to have this exported from dll:
///export.h///
#include

It SHOULD work but this is an area still in flux.
You might expand on the explanation of how it fails:
Some observations:
There should be no need to include the header
is it possible to have this exported from dll:
///export.h///
#include
class session_record { virtual void print_on(std::ostream& os) const = 0; friend std::ostream & operator<<(std::ostream& os, const session_record& sr){ sr.print_on(os); return os; } public: friend class boost::serialization::access; virtual ~session_record(); template<class Archive> void serialize(Archive & ar, const unsigned int file_version){} operator session_record *(); };
void serialize(session_record* derived, const char* file_name); session_record* deserialize(const char* file_name);
///end of export.h///
and then in an application (linked to the dll that exports all from export.h) I create derived classes from session_record and serialize or deserialize them to/from files using the two exported free functions. I followed exactly steps in "Runtime Casting" of the manual, but it doesn't work. So... is it really runtime if it doesn't work this way - it only works if all the derived classes are known & registered at the time of compilation of the two functions. All that worked well if everything from export.h was linked statically, but not dynamically
Am I doing something wrong with all that stuff?? thanks

Robert Ramey wrote:
It SHOULD work but this is an area still in flux.
You might expand on the explanation of how it fails:
It throws "unregistered class", but when I use it as statically linked lib then everything works as expected.
Some observations:
There should be no need to include the header
The serialization code will be instantiated only when code like ar << session_record is encountered. Since your DLL code doesn't include your any archives no code is generated.
Yes, there's no need to include
The first step to making this work is to look at the demo which compiles serialization code in separate modules. This shows how to instantiate the required code. Also look at polymorphic archives which permit application code to be compiled to a common interface.

__PPS__ wrote:
Yes, there's no need to include
, it could be removed from the export.h, but it doesn't mean that my DLL code doesn't include archives' code. Inside implementation of this (de)serialize functions (somewhere inside export.cpp, or whatever) I include all the archives code etc. basicly, here's export.cpp ///// //all needed includes & using namespace ...
#include "export.h" session_record::~session_record(){} session_record::operator session_record *(){ return this; }
void serialize(session_record* derived, const char* file_name){ ofstream out(file_name); if(!out || !out.is_open()) throw std::runtime_error(std::string("failed to open \"")+file_name+'"'); text_oarchive oa(out, no_header | no_codecvt); oa & derived; } session_record* deserialize(const char* file_name){ ifstream in(file_name); text_iarchive ia(in, no_header | no_codecvt); session_record *derived; ia & derived; return derived; } /////////
then in another app, that links to export.dll I have: /// needed includes & using declarations ... #include "export.h"
class client_record : public virtual session_record { friend class boost::serialization::access; template<class Archive> void serialize(needed args...){ serialization::base_object
(*this); ar & name; ar & address; ar & amount; } virtual void print_on(std::ostream &os)const{ os << "client record: \n" "\tname: " << name << "\n"; //.... } public: std::string name, address; double amount; }; BOOST_CLASS_EXPORT(client_record); main()try{
client_record x; x.name = "John Doe"; x.amount = 129.99; x.address = "2080 Wellington, apt. 13"; serialize(&x, "xxx.txt");
}catch (const exception &e) { cout << "error: " << e.what() << endl; }
/////////
I get unregistered class exception. I use vc71 and if I now in settings for the export.dll change project type from Dll to static library, and recompile my test program, everything works as expected. and this error I get is from serializing from base pointer, not from deserializing...
one other thing...
inside section "Runtime casting" there's 2nd method for registering
derived class:
boost::serialization::void_cast_register

one other thing... inside section "Runtime casting" there's 2nd method for registering derived class: boost::serialization::void_cast_register
(); it seems that it was changed or something, but it doesn't work for me. vc ide shows that this function expects 2 arguments. I also tried to call it this way: boost::serialization::void_cast_register (this,this); but it also didn't seem to work i use boost 1.33.0
whoops, your right the documentation is out of sync with the code.
Look into test_void_cast for hot its used. In your case try:
The correct function prototype is:
void_cast_register
participants (2)
-
__PPS__
-
Robert Ramey