
[Serialization] (Commented) assertion when using types in multiple DLLs on Windows (Ticket #3934 and #4394) ----------------------------------- ## Problem: We were using boost serialization in a DLL that is "statically" loaded into our main application. We are using Boost 1.44 and the serialization library as a DLL. (boost_serialization-vc80-mt-gd-1_44.dll) Now, the serialized types that we are using in this DLL have also been pulled into the main application -- that is, the .h+.cpp files of these types are included and linked in the exe as well as in the DLL project. (But the types are used independently in the exe and the dll module.) In Boost 1.44 this leads to a runtime assertion in void_cast.cpp[1_44_0, line 230]. ## Investigation: Since this code is in the function called void_caster::recursive_register I *assume* that this is the point where the types registered for serialization are registered with the library. I have found that this runtime assert was commented out in release 1.45 and all subsequent versions: std::pair<void_cast_detail::set_type::const_iterator, bool> result; // comment this out for now. result = s.insert(this); //assert(result.second); *Apparently* this was done in response to trac ticket #4394[1], at least judging from the comment Robert Ramey added to the ticket:
For now I'm going to comment out the assert. When I have time, I'll likely re-enable it with a way to override it.
I can only assume that ticket #3934[2] refers to the same or a similar problem. ## Issue with the conclusion in #4394 Robert writes in his comment:
The problem is that the way the code is structured, you'll have multiple instances of some functions. The best way would be eliminate the source of the problem by structuring code like this: ...
and he proposes to move the `template<class Archive> void serialize` function of the classes from the header file into the cpp file. However, *our* code already does this, and we get this assertion regardless. The reason I suspect is that both the main module code as well as the DLL module code are calling into the recursive_register function to register the type, and since the code for the class is (identically) duplicated in the DLL as well as in the executable, obviously it is registered twice. ## Question: Am I correct? So, the first question obviously is whether I'm correct in my analysis. I.e., the `assert(result.second);`that is currently commented out can *never* work properly for types that live in two modules (DLLs) in the same process and Boost:serialization is used as DLL. ## Question: Any harm done? Secondly, is there any adverse effect of a type being registered twice with the serialization DLL? What will happen on unload? Is it possible the type is unloaded too early because of this setup? Note: What about accidentally identical type keys for actually different types in different DLLs? ## Question: Solutions? What is a proper solution? Should we use dllexport types, so that the type is only registered once per process? What else? Robert, I hope you can chime in on this. I'll try to add a link to this mail to the trac issue #4394. cheers, Martin [1] : https://svn.boost.org/trac/boost/ticket/4394 [2] : https://svn.boost.org/trac/boost/ticket/3934