Re: [Boost-users] [serialization] Polymorphic serialization withpolymorphic archives problem...
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. void save_exported(const char *testfile) { test_ostream os(testfile, TEST_STREAM_FLAGS); test_oarchive oa(os, TEST_ARCHIVE_FLAGS); polymorphic_base *rb1 = new polymorphic_derived1; polymorphic_derived2 *rb2 = new polymorphic_derived2; // export will permit correct serialization // through a pointer to a base class oa << BOOST_SERIALIZATION_NVP(rb1); oa << BOOST_SERIALIZATION_NVP(rb2); delete rb1; delete rb2; } 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. 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). Maybe my second problem depends on the first one. I hope that my report can be of help. Thanks in advance for your answers, Martin Lederhilger
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.
void save_exported(const char *testfile) { test_ostream os(testfile, TEST_STREAM_FLAGS); test_oarchive oa(os, TEST_ARCHIVE_FLAGS);
polymorphic_base *rb1 = new polymorphic_derived1; polymorphic_derived2 *rb2 = new polymorphic_derived2;
// export will permit correct serialization // through a pointer to a base class oa << BOOST_SERIALIZATION_NVP(rb1); oa << BOOST_SERIALIZATION_NVP(rb2);
delete rb1; delete rb2; }
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
Robert Ramey schrieb:
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.
void save_exported(const char *testfile) { test_ostream os(testfile, TEST_STREAM_FLAGS); test_oarchive oa(os, TEST_ARCHIVE_FLAGS);
polymorphic_base *rb1 = new polymorphic_derived1; polymorphic_derived2 *rb2 = new polymorphic_derived2;
// export will permit correct serialization // through a pointer to a base class oa << BOOST_SERIALIZATION_NVP(rb1); oa << BOOST_SERIALIZATION_NVP(rb2);
delete rb1; delete rb2; }
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.
Thanks for your answer, in my case I want to be able to serialize an object with a pointer to its most derived type, a pointer to it's base class, a pointer to the base class of base class, ... Actually this problem should happen with all BOOST_CLASS_EXPORT_IMPLEMENTed classes which reside in one DLL, and are serialized (+automatic register_type) in another DLL or EXE. Is the intention of the exception to prevent useres from using BOOST_CLASS_EXPORT_IMPLEMENT multiple times? If so, then the quick solution for me is to ignore the exception (the serialisation seems to work then, but I know that a solution for the library itself is much trickier). Martin
Martin Lederhilger wrote:
Thanks for your answer,
in my case I want to be able to serialize an object with a pointer to its most derived type, a pointer to it's base class, a pointer to the base class of base class, ...
Actually this problem should happen with all BOOST_CLASS_EXPORT_IMPLEMENTed classes which reside in one DLL, and are serialized (+automatic register_type) in another DLL or EXE.
Is the intention of the exception to prevent useres from using BOOST_CLASS_EXPORT_IMPLEMENT multiple times?
My concern was that having (possibly different) implementations of code with the same signature in different modules would lead to bizarre behavior which would be impossible to track down. The problem for me is that when this happens with the serialization library, I get a message "The serialization library has a bug" which really bugs me. Worse, it takes a huge amount of time to resolve the issue.
If so, then the quick solution for me is to ignore the exception (the serialisation seems to work then, but I know that a solution for the library itself is much trickier).
Of course that works.
Martin
It's becoming clear to me that it's very common to have code with the same signature duplicated across DLLS. It should be clear why this CAN be a big problem but USUALLY won't be. It takes (a lot?) of extra effort to avoid this situation. I'm thinking about the best way to handle this. Robert Ramey
participants (2)
-
Martin Lederhilger
-
Robert Ramey