C++Protobuf

Protobuf

protobuf (protocol buffer) 是谷歌内部的混合语言数据标准。通过将结构化的数据进行序列化(串行化),用于通讯协议、数据存储等领域的语言无关、平台无关、可扩展的序列化结构数据格式。

  • 序列化: 将结构数据或者对象转换成能够用于存储和传输的格式。
  • 反序列化: 在其他的计算环境中,将序列化后的数据还原为数据结构和对象

下载安装

sudo apt install autoconf automake libtool curl make g++ unzip
https://github.com/protocolbuffers/protobuf/releases/
cd protobuf
./autogen.sh
./configure
make
make check
sudo make install
sudo ldconfig

Proto3中的数据类型限定修饰符:

repeated 表示一个数组类型

protobuf中常用的数据类型:

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

默认值

解析消息时,如果编码的消息不包含特定的单数元素,则已分析对象中的相应字段将设置为该字段的默认值。这些默认值是特定于类型的:

  • 对于字符串,默认值为空字符串。
  • 对于字节,默认值为空字节。
  • 对于布尔值,默认值为 false。
  • 对于数值类型,默认值为零。
  • 对于枚举,默认值是第一个定义的枚举值,该值必须为 0。
  • 对于消息字段,未设置该字段。它的确切值取决于语言。

举个栗子

syntax = "proto3";  //默认proto2,这里用proto3

package pt; //C++ 类似 namespace

enum EnMsgType{
  EnMsgTypeP = 0; //占位
  LOGIN_MSG = 1;  // 登录消息
  LOGIN_MSG_ACK = 2; // 登录响应消息
  LOGIN_OUT_MSG = 3; // 注销消息
  REG_MSG = 4; // 注册消息
  REG_MSG_ACK = 5; // 注册响应消息
  ONE_CHAT_MSG = 6; // 聊天消息
  ADD_FRIEND_MSG = 7; // 添加好友消息
  CREATE_GROUP_MSG = 8; // 创建群组
  ADD_GROUP_MSG = 9; // 加入群组
  GROUP_CHAT_MSG = 10; // 群聊天
}

message MsgType{
  EnMsgType msgtype = 1;
}

enum ErrCode {
  SUCCESS = 0; //正确
  FAILURE = 1; //失败
  ONLINE = 2;  //已在线
};

message FriendsInfo {
  int32 id = 1;
  string name = 2;
  string state = 3;
}

message UsersInfo{
  int32 id = 1;
  string name = 2;
  string state = 3;
  string role = 4;
}

message GroupsInfo{
  int32 id = 1;
  string groupname = 2;
  string groupdesc = 3;
  repeated UsersInfo users = 4;
}

message Login {
  MsgType msgid = 1;
  int32 id = 2;
  string pwd = 3;
}

message LoginRsp{
  MsgType msgid = 1;
  int32 id = 2;
  string name = 3;
  repeated string offlinemsg = 4;
  repeated FriendsInfo friends = 5;
  repeated GroupsInfo groups = 6;
  ErrCode errcode = 7;
  string errmsg = 8;
}

生成代码

 protoc test.proto --cpp_out=./
#include
#include "test.pb.h"

int main() {
    pt::Register reg;
    pt::MsgType* msg = reg.mutable_msgid();
    msg->set_msgtype(pt::EnMsgType::LOGIN_MSG);

    reg.set_name("cmf");
    reg.set_pwd("123456");
    std::string str;
    reg.SerializeToString(&str);    //序列化
    std::cout << str.c_str() << std::endl;

    pt::Register res;
    if (res.ParseFromString(str)) { //反序列化
        std::cout << res.msgid().msgtype() << " " << res.name() << " " << res.pwd() << std::endl;
    }

    pt::LoginRsp loginRsp;
    pt::MsgType* m = loginRsp.mutable_msgid();
    m->set_msgtype(pt::EnMsgType::LOGIN_MSG_ACK);

    loginRsp.set_id(1);
    loginRsp.set_name("cmf");
    loginRsp.set_errcode(pt::ErrCode::SUCCESS);
    loginRsp.set_errmsg("test");
    loginRsp.add_offlinemsg("nihao");

    pt::FriendsInfo *info = loginRsp.add_friends();
    info->set_name("cc");
    info->set_id(2);
    info->set_state("no");
    std::string strr;
    loginRsp.SerializeToString(&strr);
    std::cout << strr << std::endl;

    for (int i = 0; i < loginRsp.friends_size(); ++i) {
        pt::FriendsInfo info = loginRsp.friends(i);
        std::cout << info.name() << " " << info.id() << " " << info.state() << std::endl;
    }
    return 0;
}

编译运行加 -lprotobuf

转换接口

#include

using google::protobuf::util::JsonStringToMessage;

bool proto_to_json(const google::protobuf::Message& message, std::string& json) {
    google::protobuf::util::JsonPrintOptions options;
    options.add_whitespace = true;
    options.always_print_primitive_fields = true;
    options.preserve_proto_field_names = true;
    return MessageToJsonString(message, &json, options).ok();
}

bool json_to_proto(const std::string& json, google::protobuf::Message& message) {
    return JsonStringToMessage(json, &message).ok();
}

Original: https://www.cnblogs.com/chengmf/p/16631673.html
Author: 放飞梦想C
Title: C++Protobuf

原创文章受到原创版权保护。转载请注明出处:https://www.johngo689.com/712701/

转载文章受原作者版权保护。转载请注明原作者出处!

(0)

大家都在看

  • word输入罗马数字

    一、首先,打开Word文档程序,在程序主界面上方选择”插入”,点击打开。 二、然后,在菜单下选择”符号”,点击打开。 三、然后,在&…

    技术杂谈 2023年5月31日
    090
  • Servlet 学习总结

    Servlet学习笔记 Servlet学习 学习视频为:https://www.bilibili.com/video/BV1Ta4y1H7Vc IDEA的使用 IDEA的简介 ID…

    技术杂谈 2023年7月11日
    083
  • 基于STC51单片机的霓虹灯

    使用PWM驱动8个LED灯 人眼不能观察到灯光全灭 灯光要有动画效果 ​ 按照设计要求,为了更直观的说明脉冲宽度调制技术(PWM),所以霓虹灯的动画效果为流水灯形式。所需要的单片机…

    技术杂谈 2023年7月25日
    061
  • vue-admin-template包下载地址

    https://gitee.com/panjiachen/vue-admin-template/ https://github.com/PanJiaChen/vue-admin-t…

    技术杂谈 2023年7月11日
    092
  • Codeforces1573B

    问题描述 给你两个数组,a数组里面是1 – 2n中的奇数任意顺序排列组成,b数组里面是1 – 2n中的奇数任意顺序排列组成。 问你最少需要多少次操作能让a的…

    技术杂谈 2023年7月24日
    064
  • Mysql索引(究极无敌细节版)

    &#x53C2;&#x8003;&#x4E86;&#xFF1A; https://www.jianshu.com/p/ace3cd6526c4 &a…

    技术杂谈 2023年7月25日
    067
  • ArcGIS Pro SDK二次开发打开属性表

    using System; using System.Collections.Generic; using System.Linq; using System.Text; usin…

    技术杂谈 2023年5月30日
    0106
  • 在线英语词典

    https://dictionary.cambridge.org/dictionary/english-chinese-simplified/ Original: https://…

    技术杂谈 2023年6月1日
    088
  • Dockerfile 跨阶段多阶段使用 ARG 命令

    若要使 Dockerfile 的 ARG 命令可以跨多个阶段使用… 若要想 Dockerfile 的 ARG 命令可以跨多个阶段使用,需要有以下几步: 先在文件最前面使…

    技术杂谈 2023年7月10日
    061
  • 命令行net time同步时间(内网)

    域内各个服务器的时间保持一致,是一个很重要而又往往又容易被人忽略的问题,如果时间不同步或出现异常,往往会出现以下问题: 服务器上应用程序Server端无法获取准确的日期,导致反馈给…

    技术杂谈 2023年5月31日
    0101
  • Python基本语法学习

    CSN Python学习作业 Python的变量不需要声明,但每个变量在使用前都必须赋值。在Python中,变量就是变量,它没有所谓的”类型”一说 Pyth…

    技术杂谈 2023年7月11日
    073
  • 1001 Attention 和 Self-Attention 的区别(还不能区分我就真的无能为力了)

    通过 pytorch 去构建一个 transformer 的框架 不是导包,不是调包侠 注意力机制是一个很宽泛(宏大)的一个概念,QKV 相乘就是注意力,但是他没有规定 QKV是怎…

    技术杂谈 2023年5月31日
    098
  • linux用户身份与文件权限

    tips:可以将安装好的系统设置为一次快照,这样即便系统彻底崩溃了,也可以在5秒的时间内快速还原出一台全新的系统,而不用担心数据丢失 1、用户身份和能力 Linux系统的管理员之所…

    技术杂谈 2023年7月11日
    074
  • 代码生成器

    Mybatis Generator 使用xml配置文件形式自动生成 只生成实体类、mapper接口及mapper.xml。并且包含丰富的内容 首先添加mybatis依赖和相关插件 …

    技术杂谈 2023年6月21日
    094
  • maven的安装和仓库的种类和彼此关系

    ; ; Maven软件的下载 为了使用Maven管理工具,哦我们首先要到官网去下载他的安装软件,通过百度搜索Mav嗯如下: 点击Download连接,就可以直接进入到Maven软件…

    技术杂谈 2023年6月21日
    0106
  • Flink如何处理update数据

    问题 Flink实时统计GMV,如果订单金额下午变了该怎么处理 具体描述 实时统计每天的GMV,但是订单金额是会修改的。 订单存储在mysql,通过binlog解析工具实时同步到k…

    技术杂谈 2023年7月11日
    0108
亲爱的 Coder【最近整理,可免费获取】👉 最新必读书单  | 👏 面试题下载  | 🌎 免费的AI知识星球