Ten Points Random

Using shared_from_this inside boost::serialization

by on Dec.01, 2012 @ 06:13 pm, under Programming

Didn’t find a solution foe this on the Internet, so I thought I’d just write this up real quick to benefit anyone that was having the same issue.

If you are using boost::serialization and shared_ptr, you may have already discovered that all you have to do is add

#include <boost/serialization/shared_ptr.hpp>

to make them work together happily.

However, if your initialization routine inside your load requires shared_from_this, you may find yourself getting

terminate called after throwing an instance of 'boost::exception_detail::clone_impl<boost::exception_detail::error_info_injector<boost::bad_weak_ptr> >'
  what():  tr1::bad_weak_ptr

when trying to call methods that require shared_from_this in s11n code.

This happens because a sahred_ptr hasn’t been created for yoru unserializing class yet. To work around this, define this macro:

//Extra to make shared_from_this available inside the saving code
//This works by asking the archive to handle (and therefore create) a shared_ptr for the data
//before the main serialization code runs.
#define ALLOW_SHARED_THIS(type) \
    template<class Archive> inline void load_construct_data(Archive &ar, type *obj, const unsigned int file_version) { \
        boost::shared_ptr<type> sharedPtr; \
        ::new(obj)type();/* create instance */ \
        ar.reset(sharedPtr, obj); /* Tell the archive to start managing a shared_ptr */ \
    }

Then use it for each class that needs the shared_from_this functionality:

namespace boost { namespace serialization {
ALLOW_SHARED_THIS(MyClass)
}}

This defines a custom constructor for your class that will create the shared_ptr for your instance before your main s11n code runs and allow your code to run peacefully.

 

1 comment for this entry:
  1. Eric Raijmakers

    Hi Jon,

    Just wanted to let you know that your post on ‘shared_from_this icw boost::serialization’ really helped me a lot today!

    There’s one thing that took me some time to figure out today so I I’ll mention it here: if (de)serializing a derived class, be sure to use ‘load_construct_data’ on the derived class, and not on the base class….

    In hindsight, it’s pretty obvious. Still it took me quite some time to discover.

    Again, thanks for your post!

    Eric

Looking for something?

Use the form below to search the site:

Still not finding what you're looking for? Drop a comment on a post or contact us so we can take care of it!

Visit our friends!

A few highly recommended friends...