2010-11-20 31 views
2

我想序列化內存映射文件上的類對象,但實際上boost序列化僅適用於文件流。這裏是一個例子:使用內存映射文件進行序列化

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

現在我不太熟悉boost,但是這段代碼在運行時失敗了。所以,任何幫助真的很感激。失敗發生在這裏本身「out_streambuf obuf(params);」。 謝謝你們!

回答

1

存檔類只是在現有的流上工作,所以您需要一個能夠讀寫映射的內存區域的流。我不知道任何現成的解決方案,所以你可能只需要編寫自己的streambuf類就可以了。一旦你有了這個,就可以輕鬆將其連接到一個標準istream

std::istream is(your_streambuf); 
boost::archive::text_iarchive ia(is); 
... 
+0

謝謝,我會嘗試。 – user352951 2010-11-21 07:59:12

3

你可能要考慮Boost.Interprocess中bufferstream

的bufferstream類提供 直接 格式的iostream接口在固定大小的存儲器 緩衝器中,保護緩衝器 溢出。

1

五年後,

#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瞧!