美文网首页
boost序列化

boost序列化

作者: zlcook | 来源:发表于2020-06-30 17:18 被阅读0次

场景

分布式程序,通过MPI发送消息,消息的内容void*, 即可能不是POD,类型中可能包含vector或其它自定义类。

涉及技术

  • Iostreams : 可以自定义输入/输出源。输入输出内容自己管理,这样你可以对得到的输出内容做一些操作。
  • Serialization : 序列化/反序列化工具,对一个POD或者非POD类序列和反序列化。
  • 上述两者的结合使用:将一个自定义的类,序列化后得到的二进制字节内容通过网络发送出去,对方收到内容后反序列化成类。这里涉及到几个问题:1. 将类序列化,利用Serialization可以实现,Serialization序列化的内容输出到std::ostream类中,所以输出可以是文件(ofstream类)、osstrem、字节流、通过Iostreams自定义的输出源。同理,输入内容也是通过istream类取得。2. 要得到序列化的字节内容,并且要清楚知道字节内容的大小,这时候,就必须通过Iostreams自定义的输出源/输入源,这样你可以自定义如何接收内容,你对管理的内容是很清楚的。

样例代码

#include <fstream>

// include headers that implement a archive in simple text format
#include <boost/archive/text_oarchive.hpp>
#include <boost/archive/text_iarchive.hpp>

// 自定义类
class gps_position
{
private:
    friend class boost::serialization::access;
  // Serialization要求提供的方法
    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() {
    // 序列化内容输出源
    std::ofstream ofs("filename");
    const gps_position g(35, 59, 24.567f);
    // 下面序列化一个实例
    {
        // 以ofs为输出源,构建oarchive (text_oarchive是其中一种)
        boost::archive::text_oarchive oa(ofs);
        // 将g实列内容进行序列化,序列化的内容最终会输出到ofs中
        oa << g;
        // archive and stream closed when destructors are called
    }

    // 从输入源中反序列化一个实例
    gps_position newg;
    {
        // 输入源
        std::ifstream ifs("filename");
        // 以ifs为输入源,构建iarchive
        boost::archive::text_iarchive ia(ifs);
        // 反序列化ifs中内容得到实例newg
        ia >> newg;
        // archive and stream closed when destructors are called
    }
    return 0;
}
  • 上述,序列化和反序列化内容都是在ofstream和ifstream中,如果我们想要得到序列化的字节数据,通过ofstream显然不行,这是就自定义一个ostream子类,即通过 Iostreams 可以自定义输入输出源,可以管理输入输出的内容。

  • 如果对POD类进行序列化和反序列化,其序列化内容是字节内容,可以不用Serialization,因为通过std::memcpy就可以实现。

    size_t capacity_ = 10000;
    char* data_ = new ValueType[capacity_]();
    // 将gps_position是个POD类
    gps_position gps;
    std::memcpy(data_,  reinterpret_cast<char*>(&gps),  sizeof(gps));

    std::memcpy(reinterpret_cast<char*>(&gps), data_ ,  sizeof(gps_position));
  • 判断是一个类是否是POD: std::is_trivially_copyable<T>::value
// pod调用这个方法
template <typename Msg>
typename std::enable_if<std::is_trivially_copyable<Msg>::value, bool>::type
OutBuffer::Add(Msg& msg) {

}

// 非pod调用这个方法
template <typename Msg>
typename std::enable_if<!std::is_trivially_copyable<Msg>::value, bool>::type
OutBuffer::Add(Msg& msg) {
}

相关文章

网友评论

      本文标题:boost序列化

      本文链接:https://www.haomeiwen.com/subject/mstnahtx.html