
On 14.12.2011 09:19, Martin B. wrote:
On 14.12.2011 09:03, Martin B. wrote:
On 13.12.2011 18:22, Robert Ramey wrote:
Martin B. wrote:
[Serialization] (Commented) assertion when using types in multiple (...) (...) ## Question: Solutions? (...) I would like to see you invest some more effort to see exactly where the extra registration comes from.
Well, see my call-stack above and I'll dump a sourcecode sketch below. This does reproduce the thing for me, but other that ignoring the assert (upgrading to boost 1.48) I haven't tried any approaches yet.
Okay. Now, for this my testproject, I have been able to make it "just work" without the assertion by:
1. Removing the Types.cpp file from the executable (this will obviously initially give an unresolved external warning for Derived::* members)
2.) Make Derived a DLL export class, that is: class DLL_API Derived : ... with the usual (...)
To my surprise it compiles, links, and runs correctly. (And the type is only registered once, namely from the DLL.)
Now I'll just have to check if this solution can be applicable for our real projects, where we currently use BOOST_CLASS_EXPORT() instead of the split versions and we have a multitude of derived classes.
So maybe the assertion made sense after all. (Though I think this should be configurable on a type by type basis should it ever be reenabled.)
OK, we have now adapted our real project types and it seems it's working out well. So, to summarize: * The notification *makes* kind of sense, although it really isn't an error[1] but a nice warning and so the *unconditional* assert is rather inappropriate I think. * I guess the situation as it stands with the disabled assert is better that the situation before with the unconditionally enabled assert. For future improvements, I think that the BOOST_CLASS_EXPORT_* macros need to provide a way to specify the desired checking level on a case by case basis. (And the appropriate documentation for the firing assertion.) * Making these Types DLL-exported and defining their implementation only in the DLL worked for us, and in general, should probably work for most types where this problem occurs, because in this context you already have the situation of multiple DLLs+EXE, and you're just moving the implementation of the type to a single place. * [Speculation on my part:] If the types live in a static lib that is used by different modules of the same process, things do get more complicated, as it then should be more difficult to DLL-export the types. But maybe one could work around this by not using the serialization lib as a DLL but instead as a static lib. (Obviously would lead to code bloat, but you're already living with duplicated implementation code for the types in each module in this case anyway.) [1]: Wrt. "not an error" - The assertion was harmless for our code, but the situation could (I have not tested it) be potentially disastrous for dynamically loaded and unloaded DLLs that use the same types as another module in the process. If I understood correctly, if the serialization registration is done twice for a type, the first DLL to use it and being unloaded will unregister the type, thus breaking serialization for this type for all other modules. I haven't reproduced this, so it's largely hypothetical at this point (are there any open tickets wrt. this?). I'm also still unsure if only those types that use BOOST_CLASS_EXPORT are affected by this problem. cheers, Martin