提升序列化提升进程间字符串

Boost Serialise a Boost Interprocess string

本文关键字:字符串 进程 升序 序列化      更新时间:2023-10-16

我有一个结构实例,它通过 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

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

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

注意一个重要的实现是,std::string被(正确)标记为用于提升序列化的"基元类型",这可以防止由于对临时字符串对象的对象跟踪而导致的头痛。请务必包含上面的标题,以确保正确的行为。

在这一点上,你们同时使用共享内存序列化对我来说有点奇怪。您很可能可以直接利用共享内存缓冲区特性 - 参见例如 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::process 间库源代码来序列化 std::vector,它与您可能需要的略有不同,因为我使用的是 1.65,因此"boost::序列化::stl::load_collection"已被弃用。

如果有更好的方法,请发布。

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