Boost 序列化一个 Boost Interprocess 字符串

Boost Serialise a Boost Interprocess string

我有一个结构实例,它通过 Boost 进程间传递给 TCP/IP 客户端,在客户端中我需要使用 Boost 序列化库对其进行序列化。由于此结构包含 boost::interprocess basic_string,因此无法直接序列化,因此我通过使用它们在序列化函数中构造 std::string 来解决此问题。

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();
}

有没有更好的方法来做到这一点而无需构造函数开销?

对于std::string包括

#include <boost/serialization/string.hpp>

成功了。老实说,我有点惊讶他们没有添加 boost::container::basic_string<> 支持——显然这是一个多年未解决的问题:https://svn.boost.org/trac10/ticket/8174

所以,我猜你现在应该手动完成。

您的 "crutches" 解决方案将是最快的胜利。老实说,我不会投入更多时间,除非我确切地知道您面临的情况。

Note One important realization is that std::string is (correctly) marked "primitive type" for boost serialization, and this prevent head-aches that you'd have due to object tracking of the temporary string objects. Be sure to include the header above to guarantee the correct behaviour.

在这一点上,你们同时使用共享内存 序列化对我来说有点奇怪。您很可能可以直接利用共享内存缓冲区的特性 - 参见例如http://www.boost.org/doc/libs/1_66_0/doc/html/interprocess/managed_memory_segments.html#interprocess.managed_memory_segments.managed_heap_memory_external_buffer)。

对于任何想要它的人,我通过 boost::interprocess 库源代码找到了序列化 std::vector 的答案,它与您可能需要的略有不同,因为我使用的是 1.65所以 'boost::serialization::stl::load_collection' 已弃用。

如果有更好的方法,请 post。

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 );
}