7

C++ Protobuf - 放飞梦想C

 2 years ago
source link: https://www.cnblogs.com/chengmf/p/16631673.html
Go to the source link to view the article. You can view the picture content, updated content and better typesetting reading experience. If the link is broken, please click the button below to view the snapshot at that time.
neoserver,ios ssh client

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 <iostream>
#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 <google/protobuf/util/json_util.h>

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();
}

__EOF__


About Joyk


Aggregate valuable and interesting links.
Joyk means Joy of geeK