Qt/C++ 序列化(protobuf方式)

一、序列化介绍

序列化是将需要的内存对象转换为字节流或者其他数据格式的过程,以便保存到文件或者传输。反序列化则是将数据还原到内存对象。

序列化后存档格式有二进制数据、XML或JSON文件等。可以按照自己的需求进行序列化。

二、protobuf介绍

Protocal Buffers(简称protobuf)是谷歌使用的一项技术标准,可以将数据保存为二进制格式,完成序列化和反序列化。

优势与缺点

(优势)跨语言、跨平台、可扩展,比XML、JSON等占用空间小,效率高。

(缺点)可读性比XML,JSON等效果差。

JSON、XML是很多行业标准,而protobuf只是Google公司的内部标准。

三、工具包生成

1. 工具包下载

在github上下载,地址:https://github.com/protocolbuffers/protobuf/releases

选择一个C++版本,下载后解压。

2. 库生成

下载cmake工具,将cmake工具configure配置好后,执行后生成protobuf相关的解决方案

打开protobuf.sln,通过你的VS编译工具,编译后生成工具及库。

四、序列化流程

1. proto文件

新建一个文本文件,为了将数据实现序列化,需要将数据整理成message(相当于结构体)的基本类型写入文件。数据保存后扩展名改为proto文件,proto文件示例如下:

上图中

(1)syntax = "proto3" 指protobuf的版本号,当前主版本为3。

(2)可以声明一个package XX,后续利用它生成的源文件会将XX替换为命名空间,将序列化的模块加入到该命名空间中。

(3)定义message内容,message内会有多个变量,每个变量有个对应的编号,而且不同变量的编号不能重复。
protobuf中常用的数据类型:

数据类型 说明
bool 布尔类型
double 64位浮点数
float 32位浮点数
int32 32位整数
int64 64位整数
uint64 64位无符号整数
sint32 32位整数,处理负数效率更高
sint64 64位整数,处理负数效率更高
string 只能处理ASCII字符
bytes 用于处理多字节的语言字符
enum 枚举类型

2. 生成序列化接口文件

打开cmd控制台,切换到前面生成protoc.exe路径,输入命令protoc ./test.proto --cpp_out=./,将会从XX.proto 文件生成相应语言(cpp,c#, java)的接口文件,然后加入到我们的项目中进行使用。

生成的文件名为Test.pb.h,Test.pb.cc

3. Qt中的配置使用

(1)定义PROTOBUF_USE_DLLS使用

(2)从原始protobuf工具包中的头文件文件夹(src)拷贝到当前项目中,并添加

(3)将你编译环境生成的libprotobuf库及路径包含引用

bash 复制代码
#switch protobuf
DEFINES += PROTOBUF_USE_DLLS

SOURCES += $$PWD/proto/test.pb.cc \
    $$PWD/pserializer.cpp

HEADERS += $$PWD/proto/test.pb.h \
    $$PWD/pserializer.h

INCLUDEPATH += $$PWD/src

win32:CONFIG(release, debug|release): LIBS += -L$$PWD/lib/release -llibprotobuf
else:win32:CONFIG(debug, debug|release): LIBS += -L$$PWD/lib/debug -llibprotobufd

4. 序列化和反序列化代码

serializeToString函数:序列化为字符串

ParseFromString函数:从字符串中反序列化

cpp 复制代码
void PSerializer::serializer()
{
    // 序列化
    testPackage::Person person;
    person.set_id(0);
    person.set_name("lihua");
    person.set_sex("man");
    person.set_age(25);

    std::string string;
    if (!person.SerializeToString(&string)) {
        qDebug() << " Serialize Failed";
    }
    qDebug() << "string" << string.c_str();

    //反序列化
    testPackage::Person person1;
    if(!person1.ParseFromString(string))
    {
        qDebug() << " Parse Failed";
    }
    qDebug() << "person1.id"   << person1.id();
    qDebug() << "person1.name" << person1.name().c_str();
    qDebug() << "person1.sex"  << person1.sex().c_str();
    qDebug() << "person1.age"  << person1.age();
}

至此,我们完成一个简单的protobuf序列化和反序列化的实现。

相关推荐
꧁Q༒ོγ꧂8 分钟前
算法详解(三)--递归与分治
开发语言·c++·算法·排序算法
李兴球24 分钟前
这个来自五线城市的C++兴趣班的程序可不一般
c++
White_Can1 小时前
《C++11:智能指针》
c++·c++11·智能指针
无限进步_1 小时前
【数据结构&C语言】对称二叉树的递归之美:镜像世界的探索
c语言·开发语言·数据结构·c++·算法·github·visual studio
im_AMBER1 小时前
Leetcode 98 从链表中移除在数组中存在的节点
c++·笔记·学习·算法·leetcode·链表
CSDN_RTKLIB1 小时前
C++取模与取余
开发语言·c++
星河耀银海1 小时前
C++开发入门——环境搭建与第一个程序
开发语言·c++·策略模式
_OP_CHEN2 小时前
【算法基础篇】(四十四)数论之欧拉定理与扩展欧拉定理深度解析:从降幂到超大规模幂运算
c++·算法·蓝桥杯·算法竞赛·欧拉定理·扩展欧拉定理·acm/icpc
liulilittle3 小时前
DeepWiki: OPENPPP2 工程价值
网络·c++·网络协议·ai·信息与通信·通信
星河耀银海3 小时前
C++面向对象编程:从基础到实战
开发语言·c++