欢迎来到尧图网

客户服务 关于我们

您的位置:首页 > 房产 > 建筑 > 简单整理下protobuf中常用的几个工具函数

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

2025/6/26 18:01:17 来源:https://blog.csdn.net/shihengzhen101/article/details/144718042  浏览:    关键词:简单整理下protobuf中常用的几个工具函数

文章目录

  • 前言
  • 使用示例
    • 定义message结构
    • 结构体赋值
    • ByteSizeLong()
    • GetTypeName()
    • DebugString()
    • ShortDebugString()
    • CopyFrom(const MessageLite& other)
    • Clear()
  • Ohters
  • 总结

前言

游戏项目中使用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%,那么最后一定会赢的,我们要做的只是按照自己的节奏不断地重复,不断地重复就好~

版权声明:

本网仅为发布的内容提供存储空间,不对发表、转载的内容提供任何形式的保证。凡本网注明“来源:XXX网络”的作品,均转载自其它媒体,著作权归作者所有,商业转载请联系作者获得授权,非商业转载请注明出处。

我们尊重并感谢每一位作者,均已注明文章来源和作者。如因作品内容、版权或其它问题,请及时与我们联系,联系邮箱:809451989@qq.com,投稿邮箱:809451989@qq.com

热搜词