【问题标题】:How to serialize into a raw memory block?如何序列化成原始内存块?
【发布时间】:2012-06-22 07:27:06
【问题描述】:

用boost序列化一个c++对象到文件真的很容易,

std::ofstream ofile( lpszFileName );
boost::archive::text_oarchive oa(ofile);
oa << m_rgPoints;

但是我怎样才能将一个 c++ 对象序列化为一个原始内存块呢?

我应该将输出文件流读入内存还是有其他更好的方法?

谢谢。

【问题讨论】:

    标签: c++ serialization boost


    【解决方案1】:

    实际上有一个二进制原始数据的序列化包装器binary_object

    你可以像这样使用它:

    // buf is a pointer to a raw block of memory, size its size
    // oa is a boost archive
    boost::serialization::binary_object buf_wrap(buf, size);
    oa << buf_wrap
    

    使用 c++17 的另一个选项是将缓冲区转换为 std::vectorstd::byte。如reference of reinterpret_cast 中所述,允许将指针强制转换为byte * 并取消引用它。因此,可以使用如下代码:

    // buf is a pointer to a raw block of memory, size its size
    // oa is a boost archive
    auto start_buf = reinterpret_cast<byte *>(buf);
    std::vector<std::byte> vec(start_buf, start_buf + size);
    oa << vec;
    

    这意味着一个副本。

    【讨论】:

      【解决方案2】:

      根据 James Kanze 的 cmets 编辑:

      你可以序列化成std::ostringstream

      std::ostringstream oss;
      boost::archive::text_oarchive oa(oss);
      oa << m_rgPoints;
      

      然后通过获取std::streambuf(调用oss.rdbuf())并在其上调用streambuf::sgetn 将数据读取到您自己的缓冲区中。

      http://www.cplusplus.com/reference/iostream/ostringstream/rdbuf/

      这样可以避免不必要的临时文件。

      【讨论】:

      • 仅作记录:ios_base::binary 标志被stringbuf 忽略;它只与filebuf (ifstream, ofstream) 真正相关。既然你只是在写,ostringstream 不是更合适。
      • 我没有意识到二进制只与 filebuf 相关。谢谢你,当然 ostringstream 会更合适。
      【解决方案3】:

      你可以编写自己的 streambuf 类,直接在你的记忆中起作用:

      class membuf : public std::streambuf
      {
      public:
        membuf( char * mem, size_t size )
        {
          this->setp( mem, mem + size );
          this->setg( mem, 0, mem + size );
        }
        int_type overflow( int_type charval = traits_type::eof() )
        {
          return traits_type::eof();
        }
        int_type underflow( void )
        {
          return traits_type::eof();
        }
        int sync( void )
        {
          return 0;
        }
      };
      

      使用这个类:

        membuf buf(address,size);
        ostream os(&buf);
        istream is(&buf);
      
        oss << "Write to the buffer";
      

      【讨论】:

      • 如果您不必提前指定缓冲区大小,这将更加闪亮。但也许这个问题暗示这是一项要求。
      【解决方案4】:

      如果我了解您需要二进制序列化boost::archive::binary_oarchive。然后你可以从流中复制数据。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 2015-05-23
        • 1970-01-01
        • 2020-08-21
        • 1970-01-01
        • 1970-01-01
        • 2013-09-16
        • 1970-01-01
        相关资源
        最近更新 更多