Re:[boost] boost::serialization Remarks

Martin Ecker wrote:
Is there work under way to improve the serialization of shared_ptr/weak_ptr? Some kind of generic mechanism to serialize other smart pointer types, such as boost::shared_array or boost::intrusive_ptr, would be very nice.
Indeed it would. I want to review the implementation of boost::shared_ptr in light of recent observations. The other ones will have to be done by someone else. Since you have a need/interest in this, perhaps you would like to do this and send it too me?
Our system consists of a number of DLLs and we need boost::serialization to be built as DLL as well. ... I might have missed some others.
Is there work under way to fix this and have working DLL builds of boost::serialization (just as there are DLL builds for, say, boost::regex)?
I have interest in addressing this. I do believe it is addressable without too much difficulty but will require some extra care. There also might be some restrictions on usage - I don't know yet.
In the documentation I would like to see a remark in the section on Export
Keys, i.e. the BOOST_CLASS_EXPORT macro, that the export macros must not be used in header files, at least not in header files included by multiple
clients, because they implement global variables that must exist only once.
My intention was the BOOST_CLASS_EXPORT be included in the header file. I believe that new static variables are created only when the header file is used together with an archive header file. So this multiple instances problem would be avoided by organizing modules so that the combination of headers only occurs once. This would mean code modules would be organized similar to the demo_pimpl example where the implementation of class serialization (invocations of ar << my_class_instance) are in separate modules from the headers rather than inline functions. Note that this will result in smaller and easier to maintain code.
One thing I also find unfortunate is that the BOOST_CLASS_EXPORT macro has
to be used at global scope and cannot be used inside namespaces. Is there a way to fix this? The same goes for BOOST_SERIALIZATION_SPLIT_FREE.
A number of people have noted this - I haven't yet found a satisfactory fix for this.
On MSVC 7.1 serialization of a std::vector<bool> doesn't work with the default implementation of the boost::serialization library.
Thanks, I'll look into this. Robert Ramey

Robert, Thanks for your quick reply.
Indeed it would. I want to review the implementation of boost::shared_ptr in light of recent observations. The other ones will have to be done by someone else. Since you have a need/interest in this, perhaps you would like to do this and send it too me?
The serialization of boost::shared_array should, in principle at least, be very similar to boost::shared_ptr. So once a good solution is found for boost::shared_ptr, I believe, it can be applied to serialize boost::shared_array as well. As for other smart pointers, I think that a lot of serialization code can be used from the code for boost::shared_ptr. In any case, I do not yet know enough about the internal structure of boost::serialization to impelement smart pointer serialization myself. But if I find the time I will look into it, but I can't promise anything. While on the topic, the current shared_ptr serialization code gives an access violation when deserializing an empty shared_ptr. To remedy this in the class shared_ptr_access the following code static void add_ref_copy(boost::detail::sp_counted_base * t){ t->add_ref_copy(); }; should be changed to check for a non-NULL pointer to the counter: static void add_ref_copy(boost::detail::sp_counted_base * t){ if (t) t->add_ref_copy(); };
Is there work under way to fix this and have working DLL builds of boost::serialization (just as there are DLL builds for, say, boost::regex)?
I have interest in addressing this. I do believe it is addressable without too much difficulty but will require some extra care. There also might be some restrictions on usage - I don't know yet.
I looked into this some more and I believe to have found somewhat of a solution (albeit a "hacky" one) for the template classes derived from extended_type_info. If you don't mind I will send you my current boost::serialization code base via private e-mail and you could maybe have a look at it. As I wrote above, I do not yet know enough about the internal structure of the library, so I can't say for sure if my changes broke anything major. In the limited tests I did with the demo samples that come with the library everything seemed to work fine though. One thing that I have not yet addressed though is the need for extended type info objects to unregister themselves from the global registry. This is important when DLLs are loaded, unloaded, and then loaded again. I believe this should be quite easy to implement. Simply make a call to some unregister function in the extended_type_info destructor, similar to the self_register call in the constructor. This actually brings me to another question: Why is the self_register call not directly in the base class constructor, i.e. in extended_type_info::extended_type_info, but rather in the deriving classes?
My intention was the BOOST_CLASS_EXPORT be included in the header file.
I don't quite understand how this can work reliably. Say, I have two DLLs. In one DLL I have class A. A's header file also contains the BOOST_CLASS_EXPORT(A) macro. Now a second DLL also needs to use this class. Therefore it will include A's header file. This will result in a static guid_initializer instance to be created in both DLLs, which is unnecessary. Also with the current code it will cause the class' extended type info to be registered twice, once in each DLL with a different extended type info object each time. I believe my code modifications will remedy this though, so it wouldn't matter if the registration happened multiple times, but it is still unnecessary. The only "proper" way I know of to avoid this is to always use the export macros in .cpp files.
This would mean code modules would be organized similar to the demo_pimpl example where the implementation of class serialization (invocations of ar << my_class_instance) are in separate modules from the headers rather than inline functions.
I've looked at that sample, but since we are trying to integrate boost::serialization into an existing project, reorganizing all of our code is pretty much out of the question. We tend to have the serialization code inlined in the header files of the class it belongs to. This has so far proven to be good for maintenance of the code as well (e.g. when a new member variable is added to a class it is harder to forget to also change the serialization code, if necessary). Best Regards, Martin Ecker TAB Austria Industrie- und Unterhaltungselektronik GmbH & CoKG http://www.tab.at

<martin.ecker@tab.at> wrote in message news:OFA3E70668.F858C3FC-ONC1256E8B.00350F65-C1256E8B.00355AB5@tab.at...
Robert,
[snip]
While on the topic, the current shared_ptr serialization code gives an access violation when deserializing an empty shared_ptr. To remedy this in the class shared_ptr_access the following code static void add_ref_copy(boost::detail::sp_counted_base * t){ t->add_ref_copy(); };
should be changed to check for a non-NULL pointer to the counter: static void add_ref_copy(boost::detail::sp_counted_base * t){ if (t) t->add_ref_copy(); };
Thanks this cleared up the access violation that I had reported in http://article.gmane.org/gmane.comp.lib.boost.devel/36786/match= The example in that email now runs properly. Although, I am having problems with my VC71 MFC application reporting memory leaks of a 24byte block corresponding to each shared_ptr loaded from an oarchive. The same result for binary, text and xml. Of course this problem is not reproducible in the example from the email link above. I'm also not sure at this point whether these are true leaks, or simply a manifestation of the VC memory tracker being confused. Jeff F
participants (3)
-
Jeff Flinn
-
martin.ecker@tab.at
-
Robert Ramey