2010-11-20 10 views
2

メモリマップファイルでクラスオブジェクトをシリアル化したいが、ブーストシリアル化はファイルストリームでしか動作しないことが判明した。ここに例があります:メモリマップファイルを使用したシリアル化

class gps_position 
{ 
private: 
    friend class boost::serialization::access; 
    // When the class Archive corresponds to an output archive, the 
    // & operator is defined similar to <<. Likewise, when the class Archive 
    // is a type of input archive the & operator is defined similar to >>. 
    template<class Archive> 
    void serialize(Archive & ar, const unsigned int version) 
    { 
     ar & degrees; 
     ar & minutes; 
     ar & seconds; 
    } 
    int degrees; 
    int minutes; 
    float seconds; 
public: 
    gps_position(){}; 
    gps_position(int d, int m, float s) : 
     degrees(d), minutes(m), seconds(s) 
    {} 
}; 

int main() { 
    // create and open a character archive for output 
    std::ofstream ofs("filename"); 

    // create class instance 
    const gps_position g(35, 59, 24.567f); 

    // save data to archive 
    { 
     boost::archive::text_oarchive oa(ofs); 
     // write class instance to archive 
     oa << g; 
     // archive and stream closed when destructors are called 
    } 

    // ... some time later restore the class instance to its orginal state 
    gps_position newg; 
    { 
     // create and open an archive for input 
     std::ifstream ifs("filename"); 
     boost::archive::text_iarchive ia(ifs); 
     // read class state from archive 
     ia >> newg; 
     // archive and stream closed when destructors are called 
    } 
    return 0; 
} 

メモリマップされたファイルを介して行うことができますか?私はWindows APIのCreateFileMappingとMapViewOfFileをメモリマッピングに使用しています。

編集:

これは私がブーストiostreamライブラリとメモリマップファイルを使用して行うことを試みたものです。

namespace io = boost::iostreams; 
typedef io::stream_buffer <io::mapped_file_source> in_streambuf; 
typedef io::stream_buffer <io::mapped_file_sink> out_streambuf; 

int main() { 
    // create and open a character archive for output 
    // std::ofstream ofs("filename"); /*commented this */ 

    boost::iostreams::mapped_file_params params; 
     params.path = "filepath"; 
    params.flags = io::mapped_file::mapmode::readwrite; 

    out_streambuf obuf(params); 
    std::ostream ofs(&obuf); 

    // create class instance 
    const gps_position g(35, 59, 24.567f); 

    // save data to archive 
    { 
     boost::archive::text_oarchive oa(ofs); 
     // write class instance to archive 
     oa << g; 
     // archive and stream closed when destructors are called 
    } 

    // ... some time later restore the class instance to its orginal state 
    gps_position newg; 
    { 
     // create and open an archive for input 
    in_streambuf ibuf(params); 
    std::istream ifs(&ibuf); 

     //std::ifstream ifs("filename"); /* commented this */ 

     boost::archive::text_iarchive ia(ifs); 

     // read class state from archive 

     ia >> newg; 
     // archive and stream closed when destructors are called 
    } 
    return 0; 
} 

私はブーストに慣れていませんが、このコードは実行時に失敗します。だから、どんな援助も本当に感謝しています。失敗はここで起こる "out_streambuf obuf(params);" ありがとうございました!

答えて

1

アーカイブクラスは既存のストリームで動作するだけなので、マップされたメモリ領域からの読み書きが可能なストリームが必要です。私はこれのための既成の解決策を知らないので、あなたはこれを行う独自のstreambufクラスを書く必要があります。あなたがこれをしたら、それは標準istreamに添付するのは簡単です:

std::istream is(your_streambuf); 
boost::archive::text_iarchive ia(is); 
... 
あなたはboost.interprocess bufferstreamに見たいと思うかもしれません
+0

ありがとう、私はそれを試みます。 – user352951

3

:bufferstreamクラスは、直接 フォーマットで のiostreamインタフェースを提供します

固定サイズのメモリでバッファ のバッファが保護されたバッファ がオーバーフローします。

1

5年後、

#include <boost/interprocess/shared_memory_object.hpp> 
#include <boost/interprocess/mapped_region.hpp> 
#include <boost/interprocess/streams/bufferstream.hpp> 
#include <boost/archive/binary_oarchive.hpp> 
#include <boost/archive/binary_iarchive.hpp> 
using namespace boost::interprocess; 
.... 
_shm = new shared_memory_object(open_or_create,shm_name,read_write); 
_shm->truncate(shm_size); 
_reg = new mapped_region(_shm,read_write); 
... 
// write the serializable structure 
obufferstream bs(static_cast<char*>(region.get_address()),_reg->get_size()); 
boost::archive::binary_oarchive arch(dynamic_cast<ostream&>(bs)); 
arch << my_struct; 
... 
// read the serializable structure 
ibufferstream bs(static_cast<char*>(_reg->get_address()),_reg->get_size()); 
boost::archive::binary_oarchive arch(dynamic_cast<istream&>(bs)); 
arch >> my_struct; 

のEtほら!

関連する問題