I corrected the problem with the DLL import. That had no discernible effect.
FWIW, I also note at this point that I have set all serializable classes to
BOOST_CLASS_IMPLEMENTATION(fully_qualified_classname,boost::serialization::object_serializable);
because I don’t save any of the archives. Since I’m only using this for immediate “over the wire” communication, I don’t need backwards compatibility.
On the tracking bug:
It would also be interesting to run your own test with the default tracking behavior to see if the symptom disappears.
I set up to run with default tracking behavior. This had no discernible effect on stopping pointer_tweak (line 527 in iserializer.hpp) from nullifying the pointer to the deserialized instance. I didn’t look to see if it had an impact on the tracking flag (not certain how I would know since now tracking *should* be on)
In the .cpp files of all serialized classes. This shouldn’t matter because I never read references to prior instances
As far as we know.
I never reference prior instances because, at least for the tests I’m running, the data structures don’t contain pointers. They do contain members that are also defined in the library. These members are never, at least in the tests I’m running, handled via pointers. In addition, I using this facility to serialize data that I send “over the wire” one data structure at a time. In each case I open a new archive to serialize one data structure instance, then extract the buffer created and close the archive. Similarly, on the receiving side, I open an archive for each structure I deserialize, do the deserialization, then close the archive (in both cases the archive stack variables go out of scope). It may be that on the receive side that there is some static data in the serialization library that thinks it needs to turn serialization on – I don’t know. I haven’t dug into that.
Using/not using tracking is subservient to actually getting the deserialized data, so I’ll leave it with the default behavior for now. There remains the core problem that the call to pointer_tweak on line 527 of iserailzer.hpp causes the t pointer (the one containing the deserialized data) to be nullified.
Digging into pointer_tweak, it appears that the problem lies in void_upcast(lines 314-334) in void_cast.cpp. While it receives the appropriate type information for both the base and derived class, it cannot find any info in the void_caster_register (which has size zero) to tell it how to convert one to the other, so it returns null. (line 333). It does not throw an unregistered_cast() exception (which it seems like it should).
Could the problem lie in that because this is a DLL, its singletons (like void_caster_registry) are singletons across all EXEs that use that DLL ? Microsoft doc seems to indicate that isn’t the case (see http://msdn.microsoft.com/en-us/library/h90dkhs0(v=vs.90).aspx ) by default at least.
If there is a problem here, I could envision the following scenario: In my case, both the serializing and deserializing EXEs are running in parallel, so they could be affecting any static data in the DLL. In particular, they both could be updating and clearing the void_caster_registry. If void_caster::recursive_unregister() has been called by the serializing EXE, it may not contain anything that is now needed by the deserializing EXE. Does that make sense? Is that possible?
Regardless of what is causing the problem, should this be solvable by adding the explicit
// method 2 : explicitly register base/derived relationship
boost::serialization::void_cast_register