|
Boost Users : |
Subject: Re: [Boost-users] [serialization] deserialized instance empty even though proper serialize methods called [Honeywell Internal]
From: Hickman, Steve (AdvTech) (Steve.Hickman_at_[hidden])
Date: 2014-05-30 10:33:07
Classification: Honeywell Internal
I should have been more explicit in my original post. All serialization/deserialization is being done with base class pointers. I have a set of tests where I discovered the problems of serializing/deserializing with different pointer types that you identify below - so I've avoided that.
What you suggest for the test program is essentially what I've done in my tests.
One thing I did find in review is that somehow the serialize methods were marked protected rather than private. Fixing that partially corrected the problem. Now the deserialization "sticks" for all of the base class objects deserialized through the base class pointer (the data is in the fields after exiting the serialize process). For derived class objects deserialized through a base class pointer, I'm using xml_archive and stepping through the code. Here's what I see:
First, one thing I notice: It appears that the system thinks tracking is on (line 476 of basic_iarchive.cpp: tracking is true) even though I've consistently said
BOOST_CLASS_TRACKING(fully_qualified_classname,boost::serialization::track_never);
In the .cpp files of all serialized classes. This shouldn't matter because I never read references to prior instances, but it may indicate a problem.
The correct constructors are called in load_construct_data and the correct serialize methods are called. Further, at the end of the derived class serializer, all the fields contain the correct data - so it is loading correctly from the archive.
The deserialize works up through the return from line 516 of iserializer.hpp (call to ar.load_pointer()) (at the topmost level - I have no embedded pointers in the objects I'm using to test with). T continues to have the values loaded.
The call on line 527 of iserializer.hpp to pointer_tweak() appears to be causing the problem. It returns a null pointer. This means that the second portion of the nvp at the top level is now a null pointer, and I've lost what was loaded.
I should also note at this point that all of the relevant classes have virtual destructors. This is the only virtual method they have. Note that all of the methods on these classes are declared with the appropriate DLL import/export (since this is built as a DLL). I should also note that I was wrong from my final reply on my previous post that the warnings on locally defined symbol 'symbol' imported in function 'function' had disappeared. They only disappeared because I was inadvertently doing incremental links. My initial attempts to resolve this issue have not apparently been successful. While the Microsoft documentation indicates that the code will still work (but just run slower) in the presence of these warnings, is it possible that the downcast in pointer_tweak() is failing because of this?
I am endeavoring to correct this, but I'm a bit surprised at how the Microsoft compiler appears to be unable to chain macro definitions.
--- Steve H. From: Robert Ramey [mailto:robertmacleranramey_at_[hidden]] Sent: Thursday, May 29, 2014 2:03 PM To: boostusers_at_[hidden] Cc: robertmacleranramey_at_[hidden]; boost-users_at_[hidden]; boost-users_at_[hidden]; Hickman, Steve (AdvTech) Subject: Re: [Boost-users] [serialization] deserialized instance empty even though proper serialize methods called [Honeywell Internal] OK - this should work. But in a few rare cases it won't. Usually this due to a very unusual corner case. That case is were something isn's de-serialized exactly as it was serialized. a) serializing through a derived pointer de-serialization through a base class pointer fix - even though one knows the derived class when serializing, serialize through a pointer to the base class - effectively using an implicit cast b) some other bizarre cases I don't remember. make a pair of test program which tests your serialization. a) use xml_archives b) program A should invoke both e main(){ ... X xp1 = new X; oar << xp1; ... X xp2; iar >> xp2; assert(*xp1 == *xp2); } c) split b above into two programs Robert Ramey ============================================================================================================================================================================================================ This message classified as Honeywell Internal by Hickman, Steve (AdvTech) on Friday, May 30, 2014 at 7:33:06 AM. The above classification labels are in accordance with the Honeywell Corporate Classification Policy. The information contained in this electronic message is confidential and intended only for the use of the individual/entity named above, and the information may be privileged. If you, the reader of this message, are not the intended recipient or an employee or agent responsible to deliver this message to the intended recipient, you are hereby notified that any dissemination, distribution or copying of this communication is strictly prohibited. If you have received this communication in error, please immediately notify the sender and delete the original message. ============================================================================================================================================================================================================
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