
Robert Ramey <ramey <at> rrsd.com> writes:
Martin Lederhilger wrote:
Hello Robert, hello Bogdan,
I have quite the same problem (Exception multiple_code_instantiation
thrown in basic_serializer_map.cpp at line 48) as Bogdan. It can be
reproduced by changing
the pointer type from polymorphic_base to polymorphic_derived2 in the
original test_dll_exported.cpp example, which comes with the library.
I think the problem is that when oa << BOOST_SERIALIZATION_NVP(rb2);
is called, that the system registers an type in oserializer.hpp, which
leads to creation of the singletons also in the executeable.
Ahhhh - a very useful hint. So the rule would be that if a class
is polymorphic is to be serialized through a pointer, it should ONLY
be done through a base class pointer? That is, if ALL polymorphic
base classes are abstract - this problem will never occur?
I'll have to think about this.
I have this problem when serializing a shared_ptr<A> in class B in
B.dll to an object of class A in A.dll.
I tried to simply comment out this check, but it seems that I get
problems with tracking later. I have a class hierarchy like this:
C derives from B derives from A. A has a weak_ptr<A> to itself
(something like boost::enable_shared_from_this). If I serialize an
object of type C via a base pointer of type B the serialization walks
like this: C::serialize, B::serialize, A::serialize, and again
C::serialize (with a wrong this pointer - and it should not do that).
Hmmm - why should it not do that? You may have a cycle - but
the library handles that. Seems unrelated to the other problem.
Maybe my second problem depends on the first one. I hope that my
report can be of help.
Thanks in advance for your answers,
And thanks for your useful information.
Martin Lederhilger
Hello Robert, On your suggestion I have run a few tests. I hope they help: I commented out the registration macro associated to the base class in ExportDll.dll: - //BOOST_CLASS_EXPORT_IMPLEMENT(polymorphic_base) To make the example more realistic I modified the inheritance hierarchy as follows: class polymorphic_base{}; class polymorphic_derived1 : public polymorphic_base{}; class polymorphic_derived2 : public polymorphic_derived1{}; I added one integer data member to polymorphic_derived1 and polymorphic_derived2. Here are the results: ================================================== Polymorphic serialization through a pointer to polymorphic_base WORKS AS EXPECTED: // Save code ----------------------------- polymorphic_base *rb0 = new polymorphic_derived1(100); polymorphic_base *rb1 = new polymorphic_derived1(10); polymorphic_base *rb2 = new polymorphic_derived2(10,20); oa << BOOST_SERIALIZATION_NVP(rb0); oa << BOOST_SERIALIZATION_NVP(rb1); oa << BOOST_SERIALIZATION_NVP(rb2); // Load code ----------------------------- polymorphic_base *rb0 = NULL; polymorphic_base *rb1 = NULL; polymorphic_base *rb2 = NULL; ia >> BOOST_SERIALIZATION_NVP(rb0); ia >> BOOST_SERIALIZATION_NVP(rb1); ia >> BOOST_SERIALIZATION_NVP(rb2); The serialized content is presented below: - for polymorphic_xml_[io]archive <?xml version="1.0" encoding="UTF-8" standalone="yes" ?> <!DOCTYPE boost_serialization> <boost_serialization signature="serialization::archive" version="7"> <rb0 class_id="1" class_name="polymorphic_derived1" tracking_level="1" version="0" object_id="_0"> <polymorphic_base class_id="0" tracking_level="0" version="0"></polymorphic_base> <m_d1_>100</m_d1_> </rb0> <rb1 class_id_reference="1" object_id="_1"> <polymorphic_base></polymorphic_base> <m_d1_>10</m_d1_> </rb1> <rb2 class_id="2" class_name="polymorphic_derived2" tracking_level="1" version="0" object_id="_2"> <polymorphic_derived1 object_id="_3"> <polymorphic_base></polymorphic_base> <m_d1_>20</m_d1_> </polymorphic_derived1> <m_d2_>10</m_d2_> </rb2> </boost_serialization> - for polymorphic_text_[io]archive 22 serialization::archive 7 1 20 polymorphic_derived1 1 0 0 0 0 100 1 1 10 2 20 polymorphic_derived2 1 0 2 3 20 10 ================================================== Polymorphic serialization through a pointer to polymorphic_derived1 (i.e. the class in the middle of the hierarchy) FAILS WITH THE SAME EXCEPTION thrown about multiple registration (see the beginning of this thread). ================================================== What is worrisome though, isomorphic serialization of polymorphic_derived1 as an object followed by polymorphic serialization through a pointer to the base class FAILS WITH ACCESS VIOLATION: // Save code ----------------------------- polymorphic_derived1 rb0(100); polymorphic_base *rb1 = new polymorphic_derived1(10); polymorphic_base *rb2 = new polymorphic_derived2(10,20); oa << BOOST_SERIALIZATION_NVP(rb0); oa << BOOST_SERIALIZATION_NVP(rb1); oa << BOOST_SERIALIZATION_NVP(rb2); // Load code ----------------------------- polymorphic_derived1 rb0; polymorphic_base *rb1 = NULL; polymorphic_base *rb2 = NULL; ia >> BOOST_SERIALIZATION_NVP(rb0); ia >> BOOST_SERIALIZATION_NVP(rb1); ia >> BOOST_SERIALIZATION_NVP(rb2); The code above fails in basic_iarchive.cpp(line 469) with access violation (bpis is 0). if(! tracking){ bpis_ptr->load_object_ptr(ar, t, co.file_version); } The serialized content is presented below: - using polymorphic_xml_[io]archive <?xml version="1.0" encoding="UTF-8" standalone="yes" ?> <!DOCTYPE boost_serialization> <boost_serialization signature="serialization::archive" version="7"> <rb0 class_id="0" tracking_level="0" version="0"> <polymorphic_base class_id="1" tracking_level="0" version="0"></polymorphic_base> <m_d1_>100</m_d1_> </rb0> <rb1 class_id_reference="0" object_id="_0"> <polymorphic_base></polymorphic_base> <m_d1_>10</m_d1_> </rb1> <rb2 class_id="2" class_name="polymorphic_derived2" tracking_level="1" version="0" object_id="_1"> <polymorphic_derived1 object_id="_2"> <polymorphic_base></polymorphic_base> <m_d1_>20</m_d1_> </polymorphic_derived1> <m_d2_>10</m_d2_> </rb2> </boost_serialization> - using polymorphic_text_[io]archive 22 serialization::archive 7 0 0 0 0 100 0 0 10 2 20 polymorphic_derived2 1 0 1 2 20 10 ================================================== Isomorphic serialization of a class not related to the hierarchy as an object followed by polymorphic serialization through a pointer to the base class WORKS AS EXPECTED. ================================================== I am looking forward to hearing your conclusions. Thank you, Bogdan