Hi,
kmdarkmaster a écrit : Dear Boost community,
My problem is simple : I need to serialize a derived class (named Plugin) of a c++ class (named Base) in my main program.
The derived class Plugin is declared in a DLL which is load explicitely during execution.
I tried to use the macro BOOST_CLASS_EXPORT_GUID (as in the doc), this works perfectly if the derived class is in the main execution, i think you should read: it works perfectly if *BOOST_CLASS_EXPORT_GUID* is in the main execution. you can still put your derived class wherever you want !
but will give me an exception what exception ?
if the derived class is in the plugin DLL.
It looks like an issue I've met a few weeks ago. After investigation (note may be I'm wrong but I can only report of my understanding which is far to be good !) I now believe it is NOT possible to scatter such serialization export bits in different places (DLL vs executable, DLL vs DLL). It is because, as far as I understand the concept, the "export" mechanism you mentioned is implemented in the DLL object scope (probably using some static 'local' dictionary instantiated in the DLL scope or the executable scope, depending of the user). You can imagine such case: your base class is registered in the DLL but your Daughter class is registered at the level of the executable object scope : thus there is no way to make them communicate about their relationship. Both dictionaries (one per instantiation unit) acts in different words and know only one subset of the serializable classes to be used in your executable. The solution for me was to make sure that ALL my serialization code, together with the associated export stuff mechanism ,is instantiated in one and only one place: the executable. At least, I do not pollute my DLLs with some serialization related instantiations that may be I won't use in some of my other executables. In your case, I think you could step back to the previous approach where all serialization stuff is instantiated in the executable. The alternative is to probably to move your xml_archive ser/deser code in some resource implemented in the DLL and promote some reader and writer classes for XML archives as an element of your DLL, the later being the unique place to safely embed the problematic bits. I'm afraid there is not intermediate. You may find this "feature" annoying or even disappointing. However, it is not a bug ! It is a conceptual choice made by Robert for the Serialization lib. It is not as bad as you could think at a first glance. IMHO it is a good design not to have a central export registration 'manager'. Otherwise, such a beast would encourage developpers to add large amount of instantiated serialization/export code in any DLL for large collection of serializable classes, with some consequence to possibly end up with lots of unused serialization code being linked for nothing. I also think this would break the "template" spirit and probably could lead to performance issues if thousands of inherited classes from several independant DLLs were registered in one single central place. With the current implementation of the lib, users are forced to do a careful analysis of what they need from the executable in term of base-pointer oriented serialization. They have to manage to instantiate the only serialization bits strictly necessary for their I/O. The corresponding template code that will be generated is thus minimal. I recommend you not to use the *EXPORT* macro in your class header file, as well as instantiation code of the template "serialize" methods of your class. Use some kind of .ipp files for that to be included from your main program when it makes sense, and not by default in your DLL. I find this technique rather sane (of course it needs extra care, but that does not hurt, isn't it ?). Note also that if you don't want to use some "my_serialization.ipp" file, you can provide an alternative one, with different implementation of the template serialization code. I hope you find find these comments useful. Note I'm not completely sure they make sense in your situation. In the absence of more details, it is only a guess, probably not very understandable... sorry for that. Also I'm not sure to understand well the pb. I probably have a rather partial view on it. Hope some gurus will be able to raise the tone of this technical debate. I would enjoy to read more about this topic. cheers frc --
Forgive me if the problem is too obvious, this is my first time using Boost and I'm still a big noob in c++.
Here is my code :
IN THE MAIN EXECUTION :
Class Base (parent class) :
Base.h : #pragma once; #include "boost\serialization\access.hpp" #include <boost\serialization\nvp.hpp>
class Base { private: friend class boost::serialization::access; template void serialize(Archive & ar, const unsigned int version){} public: int a, b; Base(); virtual ~Base() { } virtual void func()= 0; // this is an abstract base class }
Base.cpp:
#include "StdAfx.h" #include "Base.h"
Base::Base(){ a=0; b=0; }
IN THE DLL (loaded explicitely)
Class Plugin (Child Class) :
Plugin.h:
#pragma once #include "boost\serialization\access.hpp" #include <boost\serialization\nvp.hpp> #include "boost\serialization\export.hpp" #include "Base.h"
class Plugin: public Base { private:
friend class boost::serialization::access; template void serialize(Archive & ar, const unsigned int version){ ar & BOOST_SERIALIZATION_BASE_OBJECT_NVP(Base); ar & BOOST_SERIALIZATION_NVP(a); ar & BOOST_SERIALIZATION_NVP(b); }
public: virtual void func(); };
BOOST_CLASS_EXPORT_GUID(Plugin, "Plugin")
Plugin.cpp:
#include "StdAfx.h" #include "Plugin.h"
void Plugin::func(){ a= 5; b= 6; }
THE MAIN FUNCTION (IN THE MAIN EXECUTION):
.......................................
HINSTANCE hinst= LoadLibrary(L"monDLLdynamique.dll"); if (hinst) { CreatePlugin ctor= (CreatePlugin)GetProcAddress(hinst, "CreatePlugin"); Base *test= ctor();
std::ofstream ofs3("FichierPointeursDerivedDLL.xml"); { boost::archive::xml_oarchive oa(ofs3); oa << BOOST_SERIALIZATION_NVP(test); } ofs3.close();
delete test; // calls Plugin's dtor
FreeLibrary(hinst); }
............................................
Any help will be very very appreciated !!! Thanks
-- View this message in context: http://boost.2283326.n4.nabble.com/Boost-Serialization-Problem-serializing-d... Sent from the Boost - Users mailing list archive at Nabble.com. _______________________________________________ Boost-users mailing list Boost-users@lists.boost.org http://lists.boost.org/mailman/listinfo.cgi/boost-users
-- François Mauger Groupe "Interactions Fondamentales et Nature du Neutrino" NEMO-3/SuperNEMO Collaboration LPC Caen-CNRS/IN2P3-UCBN-ENSICAEN Département de Physique -- Université de Caen Basse-Normandie Adresse/address: Laboratoire de Physique Corpusculaire de Caen (UMR 6534) ENSICAEN 6, Boulevard du Marechal Juin 14050 CAEN Cedex FRANCE Courriel/e-mail: mauger@lpccaen.in2p3.fr Tél./phone: 02 31 45 25 12 / (+33) 2 31 45 25 12 Fax: 02 31 45 25 49 / (+33) 2 31 45 25 49