相关文章推荐
正直的手电筒  ·  C++ ...·  2 周前    · 
时尚的豌豆  ·  iPhone ...·  10 月前    · 
安静的消炎药  ·  iOS ...·  2 年前    · 

cereal 介绍

Cereal 是一个head only开源的C++11序列化库,支持自定义数据类型序列化成 JSON , XML , 二进制压缩 ,反之也可以反序列化。几乎不依赖于其他第三方库(RapidJson,RadidXml),方便快速。

由于是开源项目,直接在 Github 上可以下载最新版本.

git clone git@github.com:USCiLab/cereal.git

将上一步下载下来的库包含到自己的工程路径中来,比如:

INCLUDEPATH +=$$PWD/Cereal

定义数据类型

定义自己的数据类型,编写序列化函数,以下是我自己代码中测试的类:

class QDicomTag
public:
    QDicomTag();
    ~QDicomTag();
    /*! 自定义序列化函数*/
    template <class Archive>
    friend void serialize( Archive & ar, const QDicomTag &tag, std::uint32_t const &version);
public:
    void cleanTag();
    bool loadTag(DcmDataset *pDataSet);
    bool loadTagGroup0008(DcmDataset *pDataSet);
    bool loadTagGroup0010(DcmDataset *pDataSet);
    bool loadTagGroup0020(DcmDataset *pDataSet);
    bool loadTagGroup0028(DcmDataset *pDataSet);
    std::string m_strImageType;                         // (0008,0008)
    std::string m_strSopClassUID;                       // (0008,0016)
    std::string m_strSopInstanceUID;                    // (0008,0018)
    std::string m_strStudyDate;                         // (0008,0020)
    std::string m_strSeriesDate;                        // (0008,0021)
template<class Archive>
void serialize(Archive &ar, const QDicomTag &tag, std::uint32_t const &version)
    (void)version;
    ar(cereal::make_nvp("imageType", tag.m_strImageType)
       ,cereal::make_nvp("sopClassUID", tag.m_strSopClassUID)
       ,cereal::make_nvp("sopInstanceUID", tag.m_strSopInstanceUID)

关键部分是编写序列化函数,具体序列化由序列化函数来实现,我这里为了代码整洁,序列化函数放在了类的外部,具体可以看后面的序列化函数.

开始序列化

需要包含头文件

#include "cereal/macros.hpp"
#include "cereal/specialize.hpp"
#include "cereal/version.hpp"
#include "cereal/access.hpp"
#include "cereal/cereal.hpp"
#include "cereal/archives/binary.hpp"
#include "cereal/archives/xml.hpp"
#include "cereal/archives/json.hpp"
#include "cereal/types/memory.hpp"
#include "cereal/types/string.hpp"
#include <cereal/types/vector.hpp>
#include <cereal/types/complex.hpp>
#include <cereal/types/map.hpp>
	QString strFile = "D:/dev/TestSerialization.json";
    std::ofstream os(strFile.toStdString ());
    cereal::JSONOutputArchive archive(os);
    QDicomTag tag;
    // ....这里省去tag结构的初始化工作
    archive(cereal::make_nvp("dicomTag" ,tag));	

序列化函数

序列化函数可以分为以下几种,具体类的结构如上面定义的DicomTag

定义在类的内部

  • 使用单个序列化函数
  • template<class Archive>
    void serialize(Archive &ar)
    	ar(m_strImageType, m_strSopClassUID, m_strStudyDate, m_strSeriesDate);
    

    可以根据自己需要,选择序列化的字段,序列化函数中列出的项均会被序列化,上面的写法,在序列化输出后会自动添加Value0.....字段值,为了方便可以添加自己的字段名:

    template<class Archive>
    void serialize(Archive &ar)
    	    ar(cereal::make_nvp("imageType", tag.m_strImageType)
           ,cereal::make_nvp("sopClassUID", tag.m_strSopClassUID)
           ,cereal::make_nvp("sopInstanceUID", tag.m_strSopInstanceUID)
    

    具体输出结果

    <?xml version="1.0" encoding="utf-8"?>
    <cereal>
    	<dicomTag>
    		<imageType>DERIVED</imageType>
    		<sopClassUID>1.2.840.10008.5.1.4.1.1.7</sopClassUID>
    		<sopInstanceUID>1.2.156.14702.1.1005.128.2.201607141416245011010000001</sopInstanceUID>
    	</dicomTag>
    </cereal>
        "dicomTag": {
            "imageType": "DERIVED",
            "sopClassUID": "1.2.840.10008.5.1.4.1.1.7",
            "sopInstanceUID": "1.2.156.14702.1.1005.128.2.201607141416245011010000001",
      
  • 分来save和load函数
  • template<class Archive>
    void save(Archive &ar) const
    		ar(cereal::make_nvp("imageType", tag.m_strImageType)
           ,cereal::make_nvp("sopClassUID", tag.m_strSopClassUID)
           ,cereal::make_nvp("sopInstanceUID", tag.m_strSopInstanceUID)
    
    template<class Archive>
    void load(Archive &ar) const
    		ar(cereal::make_nvp("imageType", tag.m_strImageType)
           ,cereal::make_nvp("sopClassUID", tag.m_strSopClassUID)
           ,cereal::make_nvp("sopInstanceUID", tag.m_strSopInstanceUID)
    

    上述函数,输出后结果和1相同.

    定义在类的外部

  • 使用单个序列化函数
  • class QDicomTag
    public:
        QDicomTag();
        ~QDicomTag();
        /*! 自定义序列化函数*/
        template <class Archive>
        friend void serialize( Archive & ar, const QDicomTag &tag, std::uint32_t const &version);
    template<class Archive>
    void serialize(Archive &ar, const QDicomTag &tag, std::uint32_t const &version)
        (void)version;
        ar(cereal::make_nvp("imageType", tag.m_strImageType)
           ,cereal::make_nvp("sopClassUID", tag.m_strSopClassUID)
           ,cereal::make_nvp("sopInstanceUID", tag.m_strSopInstanceUID)
        /*! 自定义序列化函数*/
        template <class Archive>
        friend void save(Archive &a, const QDicomTag &tag, std::uint32_t const &version);
        template <class Archive>
        friend void load(Archive &a, const QDicomTag &tag, std::uint32_t const &version);
    template<class Archive>
    void save(Archive &ar, const QDicomTag &tag, std::uint32_t const &version)
        (void)version;
        ar(cereal::make_nvp("imageType", tag.m_strImageType)
           ,cereal::make_nvp("sopClassUID", tag.m_strSopClassUID)
           ,cereal::make_nvp("sopInstanceUID", tag.m_strSopInstanceUID)
    template<class Archive>
    void load(Archive &ar, const QDicomTag &tag, std::uint32_t const &version)
        (void)version;
        ar(cereal::make_nvp("imageType", tag.m_strImageType)
           ,cereal::make_nvp("sopClassUID", tag.m_strSopClassUID)
           ,cereal::make_nvp("sopInstanceUID", tag.m_strSopInstanceUID)
      
  • cereal官方文档
  •