3

I'd like to use boost serilaization with an boost::interprocess::containers::vector

The serialization of a std::vector works fine by including

#include <boost/interprocess/containers/vector.hpp>

But I have a class containing a shared vector

class MyClass {
  public:
    typedef boost::interprocess::allocator<double, SegmentManager> Allocator;
    typedef boost::interprocess::vector<double, Allocator > VectorDouble;
    VectorDouble *pVar;

    template<class archive>  
    void serialize ( archive &ar, const unsigned int version ) {
        using boost::serialization::make_nvp;
        ar & make_nvp ( "data", *pVar; );  # This does not work
        # what works it creating a std::vector and copy the data
    }
...
    MyClass(){
      # creating the shared memory and the pointer ot pVarß
    }

    ~MyClass(){
      # release data
    }
}

I am getting the error:

error: ‘class boost::container::vector<double, boost::interprocess::allocator<double, boost::interprocess::segment_manager<char, boost::interprocess::rbtree_best_fit<boost::interprocess::mutex_family, boost::interprocess::offset_ptr<void>, 0u>, boost::interprocess::iset_index> > >’ has no member named ‘serialize’
alfC
  • 14,261
  • 4
  • 67
  • 118
Max
  • 340
  • 2
  • 15

2 Answers2

1

based on the header I wrote the following header which allows the serialization of an interprocess vector. More details can be found in my github repo.

Greetings Markus

#ifndef SHMFW_SERIALIZATION_INTERPROCESS_VECTOR_HPP
#define SHMFW_SERIALIZATION_INTERPROCESS_VECTOR_HPP


#include <boost/serialization/vector.hpp>
#include <boost/interprocess/containers/vector.hpp>

namespace boost { 
namespace serialization {

template<class Archive, class U, class Allocator>

inline void save(
    Archive & ar,
    const boost::interprocess::vector<U, Allocator> &t,
    const unsigned int file_version
){
    boost::serialization::stl::save_collection<Archive, boost::interprocess::vector<U, Allocator> >(
        ar, t
    );
}

template<class Archive, class U, class Allocator>
inline void load(
    Archive & ar,
    boost::interprocess::vector<U, Allocator> &t,
    const unsigned int file_version
){
#ifdef BOOST_SERIALIZATION_VECTOR_135_HPP
    if (ar.get_library_version()==boost::archive::library_version_type(5))
    {
      load(ar,t,file_version, boost::is_arithmetic<U>());
      return;
    }
#endif
    boost::serialization::stl::load_collection<
        Archive,
        boost::interprocess::vector<U, Allocator>,
        boost::serialization::stl::archive_input_seq<
            Archive, boost::interprocess::vector<U, Allocator> 
        >,
        boost::serialization::stl::reserve_imp<boost::interprocess::vector<U, Allocator> >
    >(ar, t);
}

// split non-intrusive serialization function member into separate
// non intrusive save/load member functions
template<class Archive, class U, class Allocator>
inline void serialize(
    Archive & ar,
    boost::interprocess::vector<U, Allocator> & t,
    const unsigned int file_version
){
    boost::serialization::split_free(ar, t, file_version);
}

#if ! BOOST_WORKAROUND(BOOST_MSVC, <= 1300)

/////////1/////////2/////////3/////////4/////////5/////////6/////////7/////////8
// vector<bool>
template<class Archive, class Allocator>
inline void save(
    Archive & ar,
    const boost::interprocess::vector<bool, Allocator> &t,
    const unsigned int /* file_version */
){
    // record number of elements
    collection_size_type count (t.size());
    ar << BOOST_SERIALIZATION_NVP(count);
    boost::interprocess::vector<bool>::const_iterator it = t.begin();
    while(count-- > 0){
        bool tb = *it++;
        ar << boost::serialization::make_nvp("item", tb);
    }
}

template<class Archive, class Allocator>
inline void load(
    Archive & ar,
    boost::interprocess::vector<bool, Allocator> &t,
    const unsigned int /* file_version */
){
    // retrieve number of elements
    collection_size_type count;
    ar >> BOOST_SERIALIZATION_NVP(count);
    t.clear();
    while(count-- > 0){
        bool i;
        ar >> boost::serialization::make_nvp("item", i);
        t.push_back(i);
    }
}

// split non-intrusive serialization function member into separate
// non intrusive save/load member functions
template<class Archive, class Allocator>
inline void serialize(
    Archive & ar,
    boost::interprocess::vector<bool, Allocator> & t,
    const unsigned int file_version
){
    boost::serialization::split_free(ar, t, file_version);
}

#endif // BOOST_WORKAROUND

};
};

#endif // SHMFW_SERIALIZATION_INTERPROCESS_VECTOR_HPP
Max
  • 340
  • 2
  • 15
0

if you look at the boost serialization library you have to manually define how to serialize something. All it can do is serialize the base types for you - you have to 'take it apart' for it. So as the error says it doesn't have the serialize method that it needs or you can make your own external serialize method depending if you want it to be intrusive or not.

The tutorials here are very helpful :):

http://www.boost.org/doc/libs/1_54_0/libs/serialization/doc/index.html

Eiyrioü von Kauyf
  • 4,481
  • 7
  • 32
  • 41