Search code examples
c++boostboost-serializationboost-interprocess

Boost Serialise a Boost Interprocess string


I have a struct instance which is passed to a TCP/IP client via a Boost interprocess, in the client I need to serialise it using the Boost serialise library. As this struct contains boost::interprocess basic_string's it can't serialise directly so I'm working around this by using them to construct std::string's in the serialize function.

using CharAllocator = boost::interprocess::allocator<char, boost::interprocess::managed_shared_memory::segment_manager>;
using MyShmString = boost::interprocess::basic_string<char, std::char_traits<char>, CharAllocator>;

MyShmString uuid_;


template<typename _Archive>
void save( _Archive &ar, unsigned int const version ) const
{
    ar << std::string{ this->uuid_.c_str(), this->uuid_.length() };
}

template<typename _Archive>
void load( _Archive &ar, unsigned int const version )
{
    auto tmp = std::string{};
    ar >> tmp; this->uuid_ = tmp.c_str();
}

Is there a better way to do this without the constructor overhead?


Solution

  • For anyone who wants it I found the answer by going through the boost::interprocess library source code for serialising a std::vector, it's a little different from what you may need as I'm using 1.65 so 'boost::serialization::stl::load_collection' is deprecated.

    If there's a better way to do this please post though.

    template<typename _Archive, typename _T1, typename _T2, typename _Alloc>
    inline void save( _Archive &ar, boost::interprocess::basic_string<_T1, _T2, _Alloc> const str, unsigned int const version )
    {
        boost::serialization::stl::save_collection<
            _Archive,
            boost::interprocess::basic_string<_T1, _T2, _Alloc>>( ar, str );
    }
    
    
    template<typename _Archive, typename _T1, typename _T2, typename _Alloc>
    inline void load( _Archive &ar, boost::interprocess::basic_string<_T1, _T2, _Alloc> &str, unsigned int const version )
    {
        boost::archive::library_version_type const library_version{
            ar.get_library_version()
        };
    
        boost::serialization::item_version_type item_version{ 0 };
        boost::serialization::collection_size_type count;
        ar >> BOOST_SERIALIZATION_NVP( count );
    
        if ( boost::archive::library_version_type( 3 ) < library_version )
        {
            ar >> BOOST_SERIALIZATION_NVP( item_version );
        }
    
        str.reserve( count );
        boost::serialization::stl::collection_load_impl( ar, str, count, item_version );
    }
    
    
    template<typename _Archive, typename _T1, typename _T2, typename _Alloc>
    inline void serialize( _Archive &ar, boost::interprocess::basic_string<_T1, _T2, _Alloc> &str, unsigned int const version )
    {
        boost::serialization::split_member( ar, str, version );
    }