c++序列化库cereal使用介绍

cereal库实现序列化和反序列化 cereal简介 cereal是一个基于c++实现的序列化工具库,用于将c++的各种数据结构序列化成二进制流进行传输,并将二进制流反序列化成原来的数据结构。相比同用途库,cereal使用简单,仅需包含头文件,运行效率尚可,对比如下: cereal的下载和安装 cereal的官方下载地址为:http://uscilab.github.io/cereal/index.html 编译源码过程... 阅读详情
AI摘要

本文介绍Cereal库用于C++对象序列化的方法,重点演示如何处理中文字符及自定义类的序列化过程。

由来

一直以来没体会到序列化的好处,最近写了配置文件读写的类,搜索过程中发现用序列化的话可以很方便的存取,几行代码就能完成。

几种序列化库

C++上序列化的库没有c#或者java那么多,比较普遍的有2个:

1.google的protobuf库
2.boost的serialization库

它们都有各自的优势,但针对小型系统的配置文件存储的话都太大太笨重了,特别是boost的serialization库居然还要编译,几百M的库,编译要2个小时,不划算。
在github上搜索到一个cereal库,获得里高达715个star,而且虽然它不支持wstring宽格式字符,但可以使用中文作为string变量,因此是可以完美支持中文配置文件的。这里记录下它的使用。

cereal库使用

平台

注意cereal基于c++11,需要支持c++11的编译器。

下载解压

在文献3或者4里下载到压缩包,将里面的include文件夹解压缩出来,其他的不需要。

工程配置

新建win32控制台工程,将include文件夹放入工程目录里,并在项目-属性-c++引用目录里添加$(ProjectDir)include

代码

1.先来最简单的将基本数据类型保存为json文件。
引用库文件

#include <fstream>
#include <iostream>
#include <string>

#include <cereal/archives/JSON.hpp>
#include <cereal/types/vector.hpp>
#include <cereal/types/string.hpp>

然后在main里写

std::ofstream file("out.json");
	cereal::JSONOutputArchive archive(file);
	std::string s[] = { "this is a string", " 中文string也是可以支持的" };
	std::vector<double> vec = { 1.00001, 2e3, 30.1, -4, 5 };
	archive(CEREAL_NVP(vec), CEREAL_NVP(s));

运行成功后结果为一个标准json文件
这里写图片描述

2.再来最简单的读取json文件到变量。
main里写

std::ifstream file("out.json");
	cereal::JSONInputArchive archive(file);
	std::string s[2];
	archive(CEREAL_NVP(s));
	std::cout << s[1];

结果很完美,对中文字符和浮点数支持都很好,不愧是715个star的项目
这里写图片描述

3.稍微复杂点的自定义类写入json
定义一个结构并添加模板函数

struct Data
{
	int index = 1;
	double d[3] = { 1.0,2.33e-5,1000000.0 };
	std::vector<std::string> vs;

	template <class Archive>
	void serialize(Archive & ar)
	{
		ar(index, d, vs);
	}
};

在main中

	Data mydata;
	std::string s1 = "中文字符串/*-+!@#$%^&";
	std::string s2 = "english/*-+!@#$%^&";
	mydata.vs.push_back(s1);
	mydata.vs.push_back(s2);
	std::ofstream file("out.json");
	cereal::JSONOutputArchive archive(file);
	archive(CEREAL_NVP(mydata));

结果同样符合预期
这里写图片描述
注意这里的项目-值对里的项目都是默认的value0-value2,并不是结构的变量名,如果想在json文件里保存到变量名,可以用下面的方法

archive(CEREAL_NVP(mydata.index), CEREAL_NVP(mydata.d), CEREAL_NVP(mydata.vs));

这样结果便是理想的形式了
这里写图片描述

4.稍微复杂点的从json读入自定义类的变量
和基本数据类型读取archive(CEREAL_NVP(s));
不一样了,如果这样写,那么cereal将会抛出一个json异常。因为NVP找不到该变量了。要用另外一个cereal的模板cereal::make_nvp

	std::ifstream file("out.json");
	cereal::JSONInputArchive archive(file);
	int n;
	std::vector<std::string> s;
	double d[3];
	archive(cereal::make_nvp("mydata.index", n));
	archive(cereal::make_nvp("mydata.d", d));
	archive(cereal::make_nvp("mydata.vs", s));
	std::cout << s[1] << '\t' << s[0] << '\t' << d[1]; 

便能正确读入这些变量了。
注意,保存的格式要为archive(CEREAL_NVP(mydata.index), CEREAL_NVP(mydata.d), CEREAL_NVP(mydata.vs));时上面的代码才能正确读取。尝试了几次,按照archive(CEREAL_NVP(mydata));反序列化时都会抛出异常,如果谁知道怎么正确读取请告诉我

4.嵌套的自定义类写入json

假设有如下结构

struct Dat
{
	int x;
	int y;
};


struct Data
{
	Dat dat = { 2,3 };
	int index = 1;
	double d[3] = { 1.0,2.33e-5,1000000.0 };
  	std::vector<std::string> vs;
};

想在保存的文件里,完整的存贮结构变量名,怎么办呢,方法如下:

struct Dat
{
	int x;
	int y;
	template <class Archive>
	void serialize(Archive & ar)
	{
		ar(cereal::make_nvp("x", x), cereal::make_nvp("y", y));
	}
};


struct Data
{
	Dat dat = { 2,3 };
	int index = 1;
	double d[3] = { 1.0,2.33e-5,1000000.0 };
	std::vector<std::string> vs;
	template <class Archive>
	void serialize(Archive & ar)
	{
		ar(cereal::make_nvp("Dat", dat), cereal::make_nvp("index", index), cereal::make_nvp("d", d), cereal::make_nvp("vs", vs));
	}
	
};

序列化保存的时候

Data mydata;
	mydata.dat.x = 50;
	mydata.dat.y = 150;
	std::string s1 = "中文字符串/*-+!@#$%^&";
	std::string s2 = "english/*-+!@#$%^&";
	mydata.vs.push_back(s1);
	mydata.vs.push_back(s2);
	

	std::ofstream file("out.json");
	cereal::JSONOutputArchive archive(file);
	archive(cereal::make_nvp("mydata", mydata));

反序列化读取的时候

std::ifstream file("out.json");
	cereal::JSONInputArchive archive(file);
	Data mydata;
	archive(cereal::make_nvp("mydata", mydata));
//要修改某个配置的时候
	mydata.index = 45;
//再序列化回去
	std::ofstream file2("out.json");
	cereal::JSONOutputArchive archive2(file2);
	archive2(cereal::make_nvp("mydata", mydata));

结果如图:

这里写图片描述

自定义类的序列化

cereal虽然很好,但只支持STL的类,在Qt里不支持Qt下的很多类,比如QVector、QList、QString。其实很好处理,重载一下就可以,上代码

namespace cereal {
template<class Archive, class c> inline
void save(Archive &ar, QVector<c> const &v)//QVector序列化
{
    for (int i = 0; i < v.size(); i++)
        ar(v.at(i));
}
template<class Archive, class c> inline
void load(Archive &ar, QVector<c> &v)
{
    v.clear();
    while (true)
    {
        const auto namePtr = ar.getNodeName();

        if (!namePtr)
            break;
        int value;
        ar(value);
        v.push_back(value);
    }
}

template<class Archive> inline
void save(Archive &ar, QString const &s)//QString序列化
{
    ar(cereal::make_nvp("str", s.toStdString()));
}

template<class Archive> inline
void load(Archive &ar, QString &s)
{
    s.clear();
    while (true)
    {
        const auto ptr = ar.getNodeName();
        if (!ptr)
            break;
        std::string value;
        ar(value);
        s = QString::fromStdString(value);
    }
}
}

使用的时候就可以和其他std库的类一样用了,这里特别提一下中文变量

std::ofstream file("out.json");

    {
        cereal::JSONOutputArchive::Options opts(3);
        cereal::JSONOutputArchive oarchive(file, opts); // Create an output archive

        MyClass m1(1, 33.322f, QStringLiteral("sdfef中文"), 234);
        m1.va.push_back(222);
        m1.va.push_back(33);
        oarchive(CEREAL_NVP(m1));
    }

    std::ifstream file2("out.json");
    {
        cereal::JSONInputArchive iarchive(file2); // Create an output archive

        MyClass m2;

        iarchive(m2);
        qDebug()<<m2.x<<m2.y<<m2.str<<m2.data.a<<m2.va.first();
    }

结果含 有正确的中文。

  • 注意,仍然不支持变量名是中文

参考文献

  1. 使用C++进行对象序列化
  2. 最常用的两种C++序列化方案的使用心得(protobuf和boost serialization
  3. cereal
  4. cereal quickstart
[WIP]C++ cereal对象序列化库使用总结 阅读详情

相关推荐

【C++】开源:数据序列化库protobuf配置与使用

protobuf学习使用

DevFrank的博客 3351

cereal:支持C++11的开源序列化库

cereal是一个基于c++实现的序列化工具库,用于将c++的各种数据结构序列化成二进制流进行传输,并将二进制流反序列化成原来的数据结构。相比同用途库,cereal使用简单,仅需包含头文件,运行效率尚可

小曹的博客 4173

Cereal库:C++11数据序列化实战指南

Cereal库是一个为C++编程语言设计的轻量级序列化库。其设计目标是提供一个简单、易用且类型安全的方式来序列化和反序列化数据。开发者在使用Cereal时,不需要编写繁琐的序列化代码,只需要通过简单的声明和宏定义,便可以实现对数据的持久化和传输,显著提升了开发效率和程序的可维护性。假设我们有一个自定义的数据类型Person,包含姓名和年龄两个字段。下面是如何使用Cereal来安全地序列化和反序列化这个类型:public:int age;// 创建一个输出归档。

weixin_28968525的博客 729

C++序列化Cereal库的使用

序列化在编程中有以下几个重要的原因:数据存储:将数据对象序列化为一种持久化的格式,可以将其存储在文件、数据库或其他存储介质中。这样可以在程序的不同运行之间保存数据的状态,以便后续使用。网络传输:当需要在网络上发送数据时,将数据序列化为一种适合传输的格式(如二进制或文本)可以确保数据能够正确地在网络中传输,并在接收端进行反序列化还原为原始的数据对象。数据交换:在不同的系统或应用程序之间进行数据交换时,序列化可以提供一种通用的格式,使得数据能够在不同的环境中被理解和处理。

m0_51415606的博客 2458

cereal序列化库及例程

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

团结引擎+OpenHarmony 2实战篇:从零构建鸿蒙应用开发环境

本文详细介绍了如何从零开始构建鸿蒙应用开发环境,重点讲解了团结引擎与OpenHarmony 2的实战配置步骤。内容包括DevEco Studio安装、OpenHarmony SDK配置、团结引擎集成及项目创建等关键环节,帮助开发者快速搭建高效的开发环境,提升鸿蒙应用开发效率。

weixin_29294395的博客 265

cereal C++11 序列化库介绍

cereal是一个只包含头文件的C++11序列化库cereal支持任何类型的数据并可以将其序列化为不同形式,例如:二进制、XML或者JSON。cereal的设计理念是快速、轻量级和容易扩展;cereal没有依赖第三库而且可以轻易的将其和其他代码相。项目使用cereal的原因:(需求)给WEB用:JSON给后端用:C++对象(不够贴切)(成员变量自动序列化成JSON)

mayue_web的博客 1873

智能解决装箱问题:使用优化算法实现高效包装

装箱问题(Bin Packing Problem)是组合优化领域中的一个经典问题,主要涉及如何将一系列对象高效地装入有限数量的容器(或“箱”)中,同时满足特定的约束条件。这个问题的目标是最小化所需使用的箱子数量或者最大化箱子的装载效率,以减少空间或资源的浪费。

MindOpt_003的博客 5546

【C++11】C++11 序列化库 cereal----- 未消化,待学习

cereal —— C++11 序列化库 介绍 cereal是一个只包含头文件的C++序列化库,cereal支持任何类型的数据并可以将其序列化为不同形式,例如:二进制、XML或者JSON。 cereal的设计理念是快速、轻量级和容易扩展——cereal没有依赖第三库而且可以轻易的将其和其他代码相。 cereal 完整支持 C++11 cereal 已经支持 C++11 标准库中的所有类型了,而且 cereal 也完全支持继承和多态。为了保持 cereal 的简洁性并不降低性能,cereal 没有像

我的笔记本 1694

5分钟搞定!用ZLMediaKit搭建GB28181视频监控系统(含避坑指南)

本文提供了一份基于ZLMediaKit搭建GB28181视频监控系统的实战指南。文章详细介绍了从环境准备、核心组件(ZLMediaKit与SIP服务器)部署、摄像头配置到内外网穿透的完整流程,并重点分享了设备ID配置、防火墙设置等关键避坑经验,帮助开发者快速构建稳定可控的监控平台。

apple5的专栏 1085

RK3568 linux-5.10 rk809 声卡实现spk hp自动切换

RK3568 linux-5.10 rk809 声卡实现spk hp自动切换

目前从事linux驱动开发,多交流多学习吧 1096

cereal:C++实现的开源序列化库

闲来无事发现了一个基于C++实现的序列化工具,相比于其他(比如Boost serialization或Google protobuf,恰巧都用过,以后再介绍),使用简单,感觉不错,下面做个摸索。 cereal介绍 cereal是一个开源的(BSD License)、轻量级的、支持C++11特性的、仅仅包含头文件实现的、跨平台的C++序列化库。它可以将任意的数据类型序列化成不同的表现形式,比如二进...

SurpassLi的专栏 125

Python 爬虫实战:付费 IP 代理使用技巧与爬虫稳定性优化

付费IP代理实战指南:突破反爬与优化稳定性 本文系统讲解付费IP代理在爬虫项目中的高效应用方法。首先对比分析静态代理、动态代理和隧道代理的优缺点及适用场景,推荐高并发项目优先选择隧道代理。然后详细演示了主流代理服务商的集成方法,包括代理池的自动更新和健康检测机制。核心部分重点介绍了爬虫稳定性优化策略,如智能重试、频率控制和请求间隔优化等关键技术。最后通过压力测试验证优化效果,并提供成本控制方案,包括代理复用、错峰爬取等实用技巧。通过本教程,开发者可有效解决高并发爬虫中的IP封禁问题,显著提升系统稳定性和抗风

2503_91057718的博客 2450

Cereal,一个轻量级的 C++ 序列化库!

嗨,大家好!我是橙子。今天咱们来探索超棒的 Cereal 库,它能轻松搞定 C++数据的序列化与反序列化,就像神奇的魔法,把数据变成能存储和传输的格式,然后又能变回来,超有趣哦!快来开启学习之旅。一、Cereal 基础使用Cereal 是个超好用的 C++模块。首先得包含它的头文件哦,这就像是给我们的代码打开一扇通往序列化世界的门。#include<iostream> #includ...

一行玩python 873

SEGGER Embedded Studio初体验

先楫HPM5E00EVK开发环境搭建

hywing's blog 1109

《Autosar从入门到精通-实战篇》总目录_培训教程持续更新中...

欢迎大家订阅《Autosar从入门到精通-实战篇》,下方整理了相关博文的目录(单击蓝色字体即可跳转),方便大家获取。 本专栏旨在:扫除Autosar工具链配置过程中的障碍,加深对Autosar理论的理解。 温馨提醒: 如有疑问,可在博文的“评论区”给小编留言,进行技术交流(评论区开启了验证功能,审核通过后,会显示); 如有疑问,也可以通过博文中的第一个图片联系小编,获取专栏/博文的实时状态; 由于工作限制,仅做个人技术交流。添加好友时,请备注您的“姓名-公司-职务...

「汽车电子助手」的博客 12万+

开源项目 Cereal 使用教程

开源项目 Cereal 使用教程 项目介绍 Cereal 是一个用于序列化和反序列化 C++ 对象的库。它支持多种数据格式,包括二进制、JSON 和 XML,并且可以轻松地与各种数据结构和自定义类型集成。Cereal 的设计目标是提供高性能和易用性,使得开发者可以方便地在不同的平台和环境中传输和存储数据。 项目快速启动 安装 Cereal 首先,你需要将 Cereal 库克隆到本地: git cl...

gitblog_00272的博客 1284

Unity技术开发干货 - 总目录

总目录 欢迎大家来到 passion 的《Unity技术开发干货》开始前博主先列出学习的大纲,同时也供大家学习参考,如果有什么问题,欢迎留言。 一.Unity基础: Unity基础-脚本生命周期 Unity基础-向量 Unity基础-寻路系统 Unity基础-物理系统 Unity基础-Mecanim动画系统 Unity基础-UGUI Unity基础-灯光 Unity-UGUI之Event System Unity-2018-粒子系统 Unity-协程入门 Unity-2D物理引擎、铰链、效应器 Unity-

TxNet 4257

开源项目推荐:C++序列化库bitsery/cereal/flatbuffers

Bitsery是一个轻量级的,头文件仅依赖的C++二进制序列化库,特别为实时数据传输,尤其是游戏开发设计。它在编译时就执行跨平台要求,确保序列化后的数据不包含任何元数据,并尽可能小。Bitsery最大的特色是无需代码生成、无元数据,你可以直接使用你的类型进行序列化和反序列化。它提供了可配置的运行时错误检查,可以读写各种源,如流(文件、网络流等)或缓冲区(向量、C数组等)。通过扩展机制,你可以定制自己的序列化行为,比如细粒度的位级控制、前后兼容性以及智能和原始指针支持。

$firecat利白的代码足迹$ 1833

温度PID控制PLC程序

温度PID稳定控制程序,适用于欧姆龙PLC,对其他PLC也具有很大参考价值

老版QQ原生表情gif动态

这是老版的QQ表情,不过全是动态的的,Windows照片查看器是不会动的,可以右击用浏览器打开查看,再说一遍是老版的,只是分享给宁愿用老版也要动态的人。

[转]cereal:C++实现的开源序列化库

文章转载自https://www.cnblogs.com/lidabo/p/8143664.html 闲来无事发现了一个基于C++实现的序列化工具,相比于其他(比如Boost serialization或Google protobuf,恰巧都用过,以后再介绍),使用简单,感觉不错,下面做个摸索。 cereal介绍 cereal是一个开源的(BSD License)、轻量级的、支持C++11特...

nianjuan1990的专栏 801

SAP B1中文培訓教材_SDK

公司内部培训资料,对开发工具 ,DIAPI, UIAPI,Add-ON有详细解说

从样例出发了解序列库cereal的实现

C++序列化库cereal的实现分析 摘要:本文通过分析cereal序列化库的核心实现机制,探讨了其高效序列化的设计原理。重点研究了BinaryOutputArchive的构造过程,包括成员初始化、模板特化和基类构造。文章详细解析了cereal如何通过输出归档类(OutputArchive)管理指针映射、多态类型注册等元信息,并利用可变参数模板和完美转发实现通用序列化接口。分析表明cereal通过哈希表优化性能,支持多种标准库容器和智能指针,提供了比Boost更高效的序列化方案。

qq_47355554的博客 1001

win10 跳过U8环境检测的IE WebControls.rar

win10 安装u8的时候 提示IE WebControls 不通过,这个工具可以欺骗u8的检查。 跳过U8环境检测的IE WebControls。提示导入失败后,重新检测通过。

开源项目cereal常见问题解决方案

开源项目cereal常见问题解决方案 项目基础介绍和主要编程语言 cereal 是一个用于序列化的C++11库。它可以将任意数据类型转换为不同的表示形式,如紧凑的二进制编码、XML或JSON。cereal的设计目标是快速、轻量级且易于扩展,它没有外部依赖,可以轻松地与其他代码集成或单独使用。 新手使用注意事项及解决方案 1. 编译错误:找不到cereal头文件 问题描述:新手在编写代码时,可能会遇...

gitblog_00595的博客 962

C++ 序列化反序列化众多方式中的两种

本文举例说明两种序列化方式,第一种是使用自带的文件操作库`ifstream`对类进行二进制序列化及反序列化;第二种采用轻量级的Cereal对类进行序列化及反序列化。

众生本就皆苦的博客 1057

BambuStudio学习笔记:Cereal 库深度解析** - C++ 序列化的现代解决方案

**Cereal** 是一个轻量级、高性能的 **C++ 序列化库**,支持将对象转换为 **二进制**、**XML** 或 **JSON** 格式,并支持跨平台反序列化。其核心设计目标是 **简化代码侵入性** 和 **提升开发效率**,适用于游戏存档、网络数据传输、配置持久化等场景。

zzzkk2009的专栏 836
上一篇: 较大数据文件的读取优化过程续
下一篇: 54元阿里云上建站详细步骤
洗洗睡去
博客等级 码龄19年 277粉丝 90原创
评论 2
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00元
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值