【问题标题】:C++ Boost binary serialization of pointer constructed from Boost object_pool从Boost object_pool构造的指针的C ++ Boost二进制序列化
【发布时间】:2018-11-02 08:32:52
【问题描述】:

我的应用程序有一个类“MyClass”。它的对象是从 Boost Object_pool 构建的。

我需要通过 Boost Binary Serialization 对此类对象进行序列化/反序列化。

用于序列化 -

我从池中取出一个指针,进行一些操作并通过 Boost 二进制序列化对其进行序列化。到目前为止一切都很好。

用于反序列化 -

我获取该序列化缓冲区并使用 Boost 二进制序列化对其进行反序列化。反序列化成功发生,但在此过程中,新内存正在通过非对象池构造的 Boost 序列化机制分配。
如果我在反序列化之前从池中分配指针,则反序列化会再次在堆上分配内存,并且池中的内存轨迹会丢失。因此,我将无法重用由 boost 序列化机制分配的内存,因为它不是从池中构造的,因此无法返回给对象池。

#include <boost/archive/binary_iarchive.hpp>
#include <boost/archive/binary_oarchive.hpp>
#include <boost/serialization/binary_object.hpp>
#include <boost/pool/object_pool.hpp>
#include <iostream>
#include <sstream>
#include <string>

class MyClass
{
  public :
    friend class boost::serialization::access;
    MyClass():data(9)
    {
      std::cout << std::endl << "MyClass()" << std::endl ;
    }

template<class Archive>
  void serialize(Archive & ar, const unsigned int version)
  {
    ar & data;
  }

~MyClass()
{
}

private :
  int data ;

};


int main()
{
  try
  {

    boost::object_pool<MyClass> pool ;

    // Get object from the Pool.
    MyClass *b = pool.construct();

    // Serialization

    std::stringbuf strbuf;
    boost::archive::binary_oarchive oa( strbuf ) ;
    oa << b ;

    // Deserilaiztion

    //MyClass *a = pool.construct() ;
    MyClass *a ;

    std::stringbuf strbufr(strbuf.str()) ; 
    boost::archive::binary_iarchive ia( strbufr ) ;

     // This calls the constructor and allocates memory for the pointer.
     // If we allocates this from the pool, new memory is still allocated     
     // and we loose track of the pointer fetched from the pool.   
     ia >> a;
  }
 catch ( boost::archive::archive_exception &e )
 {
   std::cout << std::endl << e.what() << std::endl ;
 }

}

我需要什么 -

我想将缓冲区反序列化为从池中分配的指针。

翻阅Boost序列化文档,发现Binary object wrappers的概念,却导致编译错误。

主要功能:-

int main()
{
  try
  {

    boost::object_pool<MyClass> pool ;

    MyClass *b = pool.construct();

    std::stringbuf strbuf;
    boost::archive::binary_oarchive oa( strbuf ) ;
    oa << boost::serialization::binary_object(b, sizeof(MyClass) ) ;

    MyClass *a = pool.construct() ;

    std::stringbuf strbufr(strbuf.str()) ;
    boost::archive::binary_iarchive ia( strbufr ) ;

    ia >> boost::serialization::binary_object(b, sizeof(MyClass) );
  }
  catch ( boost::archive::archive_exception &e )
  {
    std::cout << std::endl << e.what() << std::endl ;
  }

}

它给出了以下编译错误:-

serializationCpy.cpp: In function ‘int main()’:  
serializationCpy.cpp:56:8: error: no match for ‘operator>>’ (operand types are ‘boost::archive::binary_iarchive’ and ‘boost::serialization::binary_object’)
 ia >> boost::serialization::binary_object(b, sizeof(MyClass) );  
    ^
serializationCpy.cpp:56:8: note: candidate is:
In file included from /home/boost_root/include/boost/archive/detail/common_iarchive.hpp:23:0,
             from /home/boost_root/include/boost/archive/basic_binary_iarchive.hpp:30,
             from /home/boost_root/include/boost/archive/binary_iarchive_impl.hpp:21,
             from /home/boost_root/include/boost/archive/binary_iarchive.hpp:20,
             from serializationCpy.cpp:1:
/home/boost_root/include/boost/archive/detail/interface_iarchive.hpp:67:15: note: Archive& boost::archive::detail::interface_iarchive<Archive>::operator>>(T&) [with T = boost::serialization::binary_object; Archive = boost::archive::binary_iarchive]
 Archive & operator>>(T & t){
           ^
/home/boost_root/include/boost/archive/detail/interface_iarchive.hpp:67:15: note:   no known conversion for argument 1 from ‘boost::serialization::binary_object’ to ‘boost::serialization::binary_object&’  

将序列化与对象池一起使用是否正确?
非常感谢您的帮助。

【问题讨论】:

  • 我刚刚用 boost vc141 和 1.65.1 编译了你的代码,完全没有编译错误..
  • 第一个版本正在编译,它是导致编译错误的第二个主要功能。我正在使用 gcc 4.8.5 和 boost 1.65.1,它给了我编译错误。

标签: c++ pointers serialization boost memory-pool


【解决方案1】:

来源于this的回答,我觉得应该是

ia >> boost::serialization::make_binary_object(a, sizeof(MyClass));

ia & boost::serialization::make_binary_object(a, sizeof(MyClass));

而不是ia &gt;&gt; boost::serialization::binary_object(b, sizeof(MyClass) );

修正其他错别字,它会变成:

#include <boost/archive/binary_iarchive.hpp>
#include <boost/archive/binary_oarchive.hpp>
#include <boost/serialization/binary_object.hpp>
#include <boost/pool/object_pool.hpp>
#include <iostream>
#include <sstream>

class MyClass
{
public:
    friend class boost::serialization::access;
    MyClass(int data) :data(data)
    {
        std::cout << "\nMyClass(" << data << ")\n";
    }

    MyClass()
    {
        std::cout << "\nMyClass()\n";
    }

    template<class Archive>
    void serialize(Archive & ar, const unsigned int version)
    {
        ar & data;
    }

    void printData()
    {
        std::cout << "Data = " << data << "\n";
    }
private:
    int data;
};

int main()
{
    try
    {
        boost::object_pool<MyClass> pool;

        MyClass *b = pool.construct(6);

        std::stringbuf strbuf;
        boost::archive::binary_oarchive oa(strbuf);
        oa << boost::serialization::binary_object(b, sizeof(MyClass));

        MyClass *a = pool.construct();

        std::stringbuf strbufr(strbuf.str());
        boost::archive::binary_iarchive ia(strbufr);

        ia >> boost::serialization::make_binary_object(a, sizeof(MyClass));

        a->printData();
    }
    catch (boost::archive::archive_exception &e)
    {
        std::cout << std::endl << e.what() << std::endl;
    }
    return 0;
}

输出:

MyClass(6)

MyClass()
Data = 6

DEMO

【讨论】:

  • 我知道 make_binary_object 返回 const binary_object 并且现在可以使用它的引用。程序正在编译,一切都按要求工作。但是,ia &amp; boost::serialization::binary_object(b, sizeof(MyClass)); 不起作用。
  • @IranjeetSingh “不起作用”是什么意思。它应该怎么做?顺便说一句,b 可能是拼写错误而不是 a(您刚刚在它之前创建的对象)?以及为什么没有使用strbufr
  • b 而不是 a 是一个错字。是的,strbufr 不需要使用。而ia &amp; boost::serialization::binary_object(a, sizeof(MyClass)); 会导致编译错误。解决方案是使用make_binary_object 而不是binary_object,因为它返回的 const 对象可以被 boost 序列化类获取和使用。
  • @IranjeetSingh 我扩展了我的答案。你喜欢吗?
  • 嘿@JHBonarius。我试图在同一个程序中领先一步,我试图序列化和反序列化的指针现在出现在std::map&lt;int, MyClass *&gt; MyMap 中。同样,MyMap 的序列化作为一个整体工作正常,但在反序列化期间从池中获取这些指针对我来说仍然是一个挑战。
【解决方案2】:

我建议创建一个value-wrapper 或使用带有自定义序列化逻辑的自定义智能指针。

binary_object 方式可以工作,但仅适用于 POD 数据类型。

【讨论】:

  • 我的类总是只包含原始数据类型。因此,如果 binary_object 技术可行,为什么它不编译。代码中可能有错误。可以给点意见或建议吗?
  • 我同意。以后有时间我会再来的。
  • 嘿@sehe 我试图在同一个程序中领先一步,我试图序列化和反序列化的指针现在出现在 std::map 我的地图。同样,MyMap 的序列化作为一个整体工作正常,但在反序列化期间从池中获取这些指针对我来说仍然是一个挑战。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2011-03-02
  • 1970-01-01
  • 2015-09-05
  • 2016-04-21
  • 1970-01-01
  • 1970-01-01
  • 2018-01-12
相关资源
最近更新 更多