Boost logo

Boost Users :

Subject: Re: [Boost-users] [Boost Serialization] Problem serializing derived class declared in DLL
From: Kolb, Jeremy (jkolb_at_[hidden])
Date: 2011-04-06 09:20:29


I was never able to get this working properly either. I really like the serialization library but it's impossible to use if you have multiple derived classes across DLLs.

Jeremy

> -----Original Message-----
> From: boost-users-bounces_at_[hidden] [mailto:boost-users-
> bounces_at_[hidden]] On Behalf Of François Mauger
> Sent: Tuesday, April 05, 2011 6:13 PM
> To: boost-users_at_[hidden]
> Subject: Re: [Boost-users] [Boost Serialization] Problem serializing
> derived class declared in DLL
>
> 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-derived-class-declared-in-DLL-tp3428913p3428913.html
> > Sent from the Boost - Users mailing list archive at Nabble.com.
> > _______________________________________________
> > Boost-users mailing list
> > Boost-users_at_[hidden]
> > 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_at_[hidden]
> 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
>
>
> _______________________________________________
> Boost-users mailing list
> Boost-users_at_[hidden]
> http://lists.boost.org/mailman/listinfo.cgi/boost-users


Boost-users list run by williamkempf at hotmail.com, kalb at libertysoft.com, bjorn.karlsson at readsoft.com, gregod at cs.rpi.edu, wekempf at cox.net