简单整理下protobuf中常用的几个工具函数

前言

游戏项目中使用protobuf作为双端协议通讯的方式,算是一种中规中矩的方法了,偶尔会需要查看序列化后的消息占用空间大小,一直都是用序列化后的字符串来查看,即使临时测试一个结构占用空间也要序列化后才能调用 .size() 函数,最近偶然间发现有个 ByteSizeLong() 可直接用于BP结构上,这倒是简单了一点点,所以把常用的几个函数列举总结一下,免的自己时间太长忘记了。

使用示例

定义message结构

在调用函数之前先定义一个结构文件吧

syntax = "proto3";
package ProtoMsg;
option go_package = "./;ProtoMsg";

message Address {                  // 地址结构
    string city = 1;
    string street = 2;
}

message Person {
    int32 age = 1;                 // 年龄
    string name = 2;               // 姓名
    bool student = 3;              // 学生
    Address address = 4;           // 地址
    map<string, string> tags = 5;  // 标签信息
    repeated int64 lucky_nums = 6; // 幸运数字
}

结构体赋值

接着我们使用C++语言给这个结构赋值,然后尝试在此基础上调用不同的函数

    ProtoMsg::Person person;
    person.set_age(18);
    person.set_name("albert");
    person.set_student(true);
    person.mutable_address()->set_city("beijing");
    person.mutable_address()->set_street("soho");
    (*person.mutable_tags())["hobby"] = "reading";
    (*person.mutable_tags())["family"] = "warm";
    person.add_lucky_nums(1);
    person.add_lucky_nums(9);

ByteSizeLong()

这是一个获取protobuf结构大小的函数,起初我找到的是 ByteSize(),但是这个函数返回值是int,现在已经不建议使用了,所以之后请直接使用 ByteSizeLong() 来获取结构大小,就像下面这样:

std::cout << "show person size [" << person.ByteSizeLong() << "] and address size [" << person.address().ByteSizeLong() << "].";

// 输出结果
// show person size [67] and address size [15].

GetTypeName()

这个函数可以获取结构的名字,有一点点元数据的意思,在输出日志时可以使内容更清晰:

std::cout << "show person type name [" << person.GetTypeName() << "] and address type name [" << person.address().GetTypeName() << "].";

// 输出结果
// show person type name [ProtoMsg.Person] and address type name [ProtoMsg.Address].

DebugString()

这个函数看名字就知道和调试信息有关,它可以打印整个结构的数据:

std::cout << "show person debug string [" << person.DebugString() << "]."

// 输出结果
// show person debug string [age: 18
// name: "albert"
// student: true
// address {
//   city: "beijing"
//   street: "soho"
// }
// lucky_nums: 1
// lucky_nums: 9
// tags {
//   key: "family"
//   value: "warm"
// }
// tags {
//   key: "hobby"
//   value: "reading"
// }
// ].

ShortDebugString()

我们发现 DebugString() 输出的内容换行较多,虽然看起来更清晰,但是不便于存入日志按行查找,要想存储日志文件中,ShortDebugString() 函数是更好的选择:

std::cout << "show person short debug string [" << person.ShortDebugString() << "].";

// 输出结果
// show person short debug string [age: 18 name: "albert" student: true address { city: "beijing" street: "soho" } lucky_nums: 1 lucky_nums: 9 tags { key: "family" value: "warm" } tags { key: "hobby" value: "reading" }].

CopyFrom(const MessageLite& other)

这个结构用于结构的拷贝,比如你已经有了一个地址结构对象,再创建新的 Person 时就不必对address字段一一赋值,而是可以直接使用CopyFrom函数完成:

    ProtoMsg::Address addr;
    addr.set_city("shanghai");
    addr.set_street("nanjinglu");
    person.mutable_address()->CopyFrom(addr);

    std::count << "show person short debug string [" << person.ShortDebugString() << "].";

// 输出结果
// show person short debug string [age: 18 name: "albert" student: true address { city: "shanghai" street: "nanjinglu" } lucky_nums: 1 lucky_nums: 9 tags { key: "family" value: "warm" } tags { key: "hobby" value: "reading" }].

Clear()

清空当前消息的所有字段,重置为默认状态,这个我倒是不太常用,但是测试时偶尔会用到:

    person.Clear();

    std::cout << "show person size [" << person.ByteSizeLong() << "] and short debug string [" << person.ShortDebugString() << "].";

// 输出结果
// show person size [0] and short debug string [].

Ohters

其他还有一些函数属于使用protobuf的常见函数,我就不再举例了,简单列举下函数作用:

  • MergeFrom(const MessageLite& other) 合并另一个消息的内容到当前消息中(可能会覆盖现有字段)
  • SerializeToString(std::string* output) 将消息序列化为字符串格式,并将结果存储在提供的 std::string 对象中
  • ParseFromString(const std::string& data) 从给定的字符串解析出消息数据
  • std::string SerializeAsString() const 将消息序列化为字符串格式并返回
  • bool SerializeToArray(void* data, int size) const 直接将消息序列化到用户提供的缓冲区中
  • google::protobuf::MessageLite::ParseFromArray(const void *data, int size) 将给定的二进制数据解析为 Protocol Buffers 消息对象

总结

  • ByteSizeLong() 可以用来获取一个protobuf结构的大小
  • GetTypeName() 可以用来返回一个结构的名字
  • ShortDebugString() 可以用返回一个结构的数据内容
  • protobuf 这种经典的开源库挖一挖总会有惊喜

==>> 反爬链接,请勿点击,原地爆炸,概不负责!<<==

慢就是快,每个人都有不同的解读,曾经有那么两次我好像都能顿悟了,可思绪闪现了那么一刻就消失了;稳稳地慢是幸运的,最近总是听人讲到控制回撤这个词,尽管他喊得声嘶力竭,起初我却不以为意,但经历的多了以后开始理解他所说的价值,才理解慢慢变富的含义,既然是概率游戏,只要能保证胜率在51%,那么最后一定会赢的,我们要做的只是按照自己的节奏不断地重复,不断地重复就好~

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

AlbertS

常来“玩”啊~

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值