c++ - Boost::Serialization and MFC Doc/View architecture -


i'm porting existing mfc c++ application use boost::serialization xml files. cdocument object contains data app. i've implemented serialize function as:

template<class archive> void cmydoc::serialize(archive& ar, const unsigned int version) { ar  & boost_serialization_nvp(m_param1)     & boost_serialization_nvp(m_param2); } 

to capture save , load events, in cdoc *.cpp file have overloaded base class functions onopendocument() , onsavedocument() implement boost::serialization:

bool cmydoc::onopendocument(lpctstr lpszpathname) { clear();    // clear current params  //if (!cdocument::onopendocument(lpszpathname)) // old mfc serialize code //  return false;  cevolvetrafficdoc* pdoc = this; // pointers same here std::ifstream ifs(lpszpathname); boost::archive::xml_iarchive ia(ifs); ia >> boost::serialization::make_nvp("mydoc",pdoc); // pointer changes here // *this = *pdoc; // possible solution cmydoc copy constructor implemented  return true; }  bool cmydoc::onsavedocument(lpctstr lpszpathname) { //if (!cdocument::onsavedocument(lpszpathname)) // old mfc serialize code //  return false;  std::ofstream ofs(lpszpathname); boost::archive::xml_oarchive oa(ofs); oa << boost::serialization::make_nvp("mydoc",this);  return true; } 

saving document works fine. problem loading document doesn't work. boost library seems copy cmydoc object because pointer comes different address. means loaded file isn't loaded current document. can cdoc overwrite boost? can mfc carchive.

i thought having line indicated "possible solution", mean implementing copy constructor cmydoc class. removes 1 of benefits of boost in have 2 lines of code each variable: 1. ar & boost_serialization_nvp(m_param1) // saving , loading pdoc 2. this->m_param1 = pdoc.m_param1 // in cmydoc copy constructor

if overload cmyview capture file open , save events, mru list management offered doc/view architecture won't happen.

i'm sure has been done million times, can't find information online. weird! appreciated :d


reading documentation closer, see boost acknowledges serialized pointer deserialized new keyword: "serialization of pointers implemented in library code similar following:"

// load data required construction , invoke constructor in place template<class archive, class t> inline void load_construct_data( archive & ar, t * t, const unsigned int file_version ){ // default uses default constructor initialize // allocated memory.  ::new(t)t(); } 

the documentation recommends overloading function if necessary:

template<class archive> inline void load_construct_data( archive & ar, my_class * t, const unsigned int file_version ){ // retrieve data archive required construct new instance int attribute; ar >> attribute; // invoke inplace constructor initialize instance of my_class ::new(t)my_class(attribute); } 

but again result in needed implement cmydoc copy constructor. aaarrgghhhh!!


in case helps anyone, had reply robert ramey this. basically, wasn't missing obvious: cmydoc serialize(archive& ar, const unsigned int version) function wasn't runner, implemented separate boost_save , boost_load functions. had overload onopendocument , onsavedocument, example:

bool cmydoc::onopendocument(lpctstr lpszpathname) { clear();

// call base class function empty local serialize function // check file exists etc if (!cdocument::onopendocument(lpszpathname))     return false;  std::string file( lpszpathname ); boost_load(file); return true; 

}

this necessary since mfc carchive owns file until mfc serialize function exits, disallowing boost::serialization access file. calling ar.abort() in serialize functions doesn't work because cdocument base class assumes ar exists on returning base class serialize function.

there's neat solution using boost.iostreams:

// mean not track class, or you'll object-tracking warnings boost_class_tracking(mydoc, boost::serialization::track_never)  void mydoc::serialize(carchive& ar) {     namespace io = boost::iostreams;     io::file_descriptor fd(ar.getfile()->m_hfile, io::never_close_handle);     io::stream<io::file_descriptor> file(fd);      if (ar.isstoring())     {         boost::archive::xml_oarchive oa(file);         oa << *this;     }     else     {         boost::archive::xml_iarchive ia(file);         ia >> *this;         // update views...     } }  template<class archive> void mydoc::serialize(archive & ar, unsigned version) {     // boost.serialization code here     ar & boost_serialization_nvp(member); } 

you don't have bother onopendocument/onsavedocument. overwrite cdocument::serialize , forward boost.serialization.


Comments

Popular posts from this blog

c# - SharpSVN - How to get the previous revision? -

c++ - Is it possible to compile a VST on linux? -

url - Querystring manipulation of email Address in PHP -