皮皮网

【em游戏制作 源码】【小猪源码能商用吗】【Java面试问底层源码】google protobuf 源码

2024-11-27 19:46:40 来源:多图片上传源码

1.Google Protobuf 极速入门使用攻略 (C++版本)
2.Protobuf入门:在linux下编译使用protobuf
3.protobuf 协议原理及实现(C++)
4.Lua动态解析Protocol buffer
5.Protobuf读写Prototxt
6.Protobuf在UE5中的源码简单使用说明

google protobuf 源码

Google Protobuf 极速入门使用攻略 (C++版本)

       要学习在C++中使用Google的Protocol Buffer,首先可以参考Git仓库:Teach-Myself-CPP/Protocol-buffer。源码Protocol Buffer作为一种灵活、源码高效且自动化的源码数据序列化解决方案,对于处理数据结构的源码序列化/反序列化问题非常有用。

       当你需要在C++中处理数据结构时,源码em游戏制作 源码有多种方法可选。源码然而,源码Protocol Buffer凭借其直观的源码定义方式脱颖而出。它的源码消息格式定义类似于C/C++中的类/结构,支持多种基础类型如int和string,源码以及嵌套类型,源码如PhoneType在PhoneNumber中,源码Person在AddressBook中。源码每个字段可以是源码required(不推荐,影响可移植性)、optional或repeated,分别对应必须存在、可选和可重复的字段值。

       安装Protocol Buffer后,通过命令行检查版本更新。然后,使用编译器将消息定义转换为cpp和h文件,小猪源码能商用吗如addressbook.pb.h和addressbook.pb.cc,它们会自动生成访问字段的getter和setter方法。

       在实际操作中,有一些通用的函数可以方便地进行消息的序列化和反序列化。例如,可以编写一个程序添加Person到磁盘文件,并反序列化文件中的数据到内存,展示详细信息。

       编译和运行程序通常通过Makefile或CMakeLists来完成,但这里我们直接在命令行进行。接下来,尝试执行序列化和反序列化的步骤,完成整个过程。

Protobuf入门:在linux下编译使用protobuf

       Google Protocol Buffer(简称Protobuf)是一种由Google公司内部开发的数据标准,用于数据序列化。广泛应用于数据存储和远程过程调用(RPC)系统。它具备语言无关性、平台无关性和可扩展性,支持C++、Java和Python等语言。

       编译源码包:从GitHub下载Protobuf的源代码,以2.5.0版本为例。Java面试问底层源码解压后,执行配置编译命令,创建文件。编译后,文件夹中将包含bin、include和lib目录。

       测试工程:将include目录下的文件按目录结构和lib/libprotobuf.a复制到测试目录。定义结构化数据Content,包含id(int)、str(string)和opt(可选成员)。使用protoc程序将Mymessage.proto文件编译成目标语言,生成Mymessage.pb.h和Mymessage.pb.cc文件。

       将编译后的Mymessage.pb.o文件与Writer.cpp文件一起编译,生成log文件。Reader从log文件读取,反序列化后获得结构化数据。

       Protobuf的优点在于高效、紧凑的二进制数据序列化方式,使其适合数据存储和RPC通信。然而,它缺乏复杂概念表示的能力,与XML相比在通用性上仍有不足。初智超 源码资本XML自解释性使其在文本描述方面优于Protobuf。

       高级应用包括嵌套消息、Import Message和动态编译。嵌套消息如Person包含PhoneNumber,用于Person中的phone域。Import Message允许在包中定义公用消息,通过包引入使用。动态编译允许在运行时处理未知的.proto文件。

       编写新编译器:利用Google Protocol Buffer源代码中的protoc编译器,可以开发支持其他语言的编译器。通过实现CodeGenerator派生类,实现代码生成功能。

       Protobuf的编码方式使用Varint表示数字,节省空间。Varint用一个或多个字节表示数字,值越小字节越少。消息序列化为紧凑的二进制数据流,无需分隔符,可优化大小。

protobuf 协议原理及实现(C++)

       protobuf协议原理及实现(C++)

       Protocol Buffers(简称ProtoBuf)是由Google设计的一种高效的数据序列化和通信协议,尤其适合高性能数据传输场景。它与XML、小程序源码 手机壁纸JSON相比,具有显著的优势,侧重于数据序列化而非数据结构化的可读性。以下是关于ProtoBuf的一些关键点:

       1. ProtoBuf的结构化数据定义使用.proto文件,通过message、import和内嵌message语法实现,但相比XML和JSON,其人类可读性较差,更适用于高效通信和存储。

       2. 安装ProtoBuf库可通过GitHub下载,选择适合的版本,例如protobuf-cpp-3..6,然后进行编译安装。验证安装成功的方法是检查protoc版本。

       3. 使用ProtoBuf时,首先创建.proto文件定义数据结构,然后通过protoc编译器生成读写接口,包括.h和.cc文件,实现序列化和反序列化操作。例如,测试代码会将Example1对象写入文件。

       4. 优化技巧包括重用message对象和使用高效的内存分配器。高级用法包括反射功能,可用于将messages转换为其他格式或执行更复杂的操作,如差异分析或正则表达式匹配。

       了解更多关于C++的ProtoBuf教程,可以参考官方文档或在线课程,如ke.qq.com/course/?...

Lua动态解析Protocol buffer

       Protocol Buffer是Google开源的一种数据存储和RPC格式,因其高效存储和低资源消耗而广泛应用于消息协议处理中。在游戏开发等领域,Protocol Buffer常作为前后端交互消息格式,利用其性能优势简化数据传输。

       为了适应手机端的动态更新需求,游戏开发者往往选择使用脚本语言,如Lua,来实现更灵活的协议设计。要将Protocol Buffer的动态解析融入Lua环境,实现协议描述文件修改后无需重新编译C++代码,关键在于设计一个能够动态加载和解析描述文件的解决方案。

       动态加载编译协议文件的目标是,在客户端启动后检测描述文件变动,更新至本地后即时加载新文件并使用新描述序列化或反序列化消息数据。这样实现后,客户端无需重新编译,仅需在Lua脚本中新增字段信息即可。

       实现这一目标需深入理解Protocol Buffer的动态编译原理。Protocol Buffer通过google::protobuf::compiler::Importer类动态编译未知描述文件,利用google::protobuf::compiler::MultiFileErrorCollector类搜集语法错误,google::protobuf::compiler::SourceTree类缓存加载的描述文件。动态编译时调用Importer对象的import方法即可实现。

       获取具体消息类的步骤中,利用Descriptor Pool的FindMessageTypeByName方法从描述文件中获取指定消息的Descriptor。通过Descriptor创建Message实例,最终目标是将Message转化为Lua table,利用Lua table的灵活性高效传递消息数据。

       将Protocol Buffer数据结构转化为Lua table,主要依赖反射机制获取Message的所有Field,并通过遍历Lua table的key-value对进行数据传递。对于repeated字段,通过嵌套table形式处理重复的key值。序列化时,同样通过动态创建Message对象并填充Lua table数据,调用SerializeToString方法完成。

       在实现中需注意处理required字段的容错和提示信息,确保Lua脚本与C++层数据交互的正确性和稳定性。动态编译Protocol Buffer到Lua脚本的实现,有效提升了游戏开发的灵活性与效率,简化了前后端交互过程,为开发者提供了更为便捷的协议设计与维护手段。

Protobuf读写Prototxt

       本文主要介绍如何读取和写入protobuf到bin文件以及读写prototxt相关API。

       protobuf将程序运行产生的数据保存到二进制文件中,相较于xml,文件更小,读取速度更快。google提供protobuf工具中包含读写bin文件API。

       message类中提供写bin文件API,原型为:std::ostream * output。message类定义数据结构的基类,封装通用接口。

       可以通过google官方API文档访问详细信息:/protocol-buffers/docs/referenc/cpp/google.protobuf.message#Message.SerializeToOstream.details

       除了按照输出流写bin文件,还支持按照文件描述符操作,其他API包括。

       示例一:在Family数据结构中添加两个成员,并将结果写入test.db文件。生成的test.db文件为加密压缩的二进制数据。

       示例二:从生成的bin文件读取数据。bin文件不仅支持写入,还支持读取,能完全恢复数据。

       示例三:使用写Prototxt文件API将添加的两个成员写入到prototxt文件。生成的文件格式类似Python元组。

       prototxt文件用于caffe中保存网络拓扑结构及参数,格式为txt形式,便于可视化修改。prototxt文件读写API在text_format.h文件中。

       示例四:使用读Prototxt文件API从生成的prototxt文件读取数据。成功将数据读取到内存中。

Protobuf在UE5中的简单使用说明

       Protocol Buffer(简称 Protobuf)是 Google 提供的一种数据存储格式,用于结构化数据的高效序列化。它支持跨多种编程语言通信,通过单一标准协议定义数据格式,自动生成语言特定的包。

       步骤1:创建proto文件。以登录消息`login.proto`为例,文件中定义了消息结构和消息ID。

       步骤2:生成对应C++文件。通过批处理脚本在`client\Plugins\BLProtobuf\Source\BLProtobuf\protoc_tools`目录下双击,即可自动生成并拷贝到`client\Source\ProjectMeta\Proto`目录。

       步骤3:注册包反射。需要在头文件中提供消息ID和消息类名,之后在回调函数中调用RegisterPackage,完成包注册。

       步骤4:实现回调函数。确保RegisterPackage调用在回调函数之后,简单地将其加入到每个回调函数文件的末尾。

       开发建议:设计子系统,如登录子系统,包含发起登录、登录回调接口。注册等接口可在子系统中扩展。

       具体C++实现代码如下,其中省略了详细代码示例,建议根据实际情况调整并添加到对应文件中。

Protobuf协议实现原理

        protobuf 是Google开源的一款支持跨平台、语言中立的结构化数据描述和高性能序列化协议,此协议完全基于二进制,所以性能要远远高于JSON/XML。由于出色的传输性能所以常见于微服务之间的通讯,其中最为著名的是Google开源的 gRPC 框架。

        那么protobuf是如何实现高性能的,又是如何实现数据的编码和解码的呢?

        基于bits的数据存储方式(Base Varints)

        Varint 是一种紧凑的表示数字的方法。它用一个或多个字节来表示一个数字,值越小的数字使用越少的字节数。这能减少用来表示数字的字节数。

        比如对于 int 类型的数字,一般需要 4 个 byte 来表示。但是采用 Varint,对于很小的 int 类型的数字,则可以用 1 个 byte 来表示。当然凡事都有好的也有不好的一面,采用 Varint 表示法,大的数字则需要 5 个 byte 来表示。从统计的角度来说,一般不会所有的消息中的数字都是大数,因此大多数情况下,采用 Varint 后,可以用更少的字节数来表示数字信息

        Varint 中的每个 byte 的最高位 bit 有特殊的含义,如果该位为 1,表示后续的 byte 也是该数字的一部分,如果该位为 0,则结束。其他的 7 个 bit 都用来表示数字。因此小于 的数字都可以用一个 byte 表示。大于 的数字,比如 ,会用两个字节来表示: 。

        另外如果从数据大小角度来看,这种表示方式比实现的数据多了一个bit, 所以其实际传输大小就多%(1/7 = 0.)。

        数字1表示方式:

        对于小的数据比较好理解,正常情况下1的二进制是 ,使用bits表示的话,首位结束标识位也是0,所以两者结果是一样的 0。

        数字 表示方式:

        <figcaption></figcaption>

        这个有点不太好理解了,这是因为原本用一个字节(8bit)就可以表示,但由于使用bits表示方法,需要对每个字节的最高位添加一个结束标识位来表示,所以一个字节已经不够用了,需要占用两个字节来表示,其中两个字节最高位都是结束标识位。

        如果正向推算的话,我们知道数字的二进制值 1 ,用两个字节表示完整值则为

        # 二进制

        _ _ # 二进制每个字节的最高位向左移动一个位置,放入结束标识位

01# 转换为bits方式,1:结束,0:未结束

10# 转换为 小端字节序 , 低字节在前,高字节在后

        注意这里是先添加结束标识符,然后再转为小端字节序。

        消息经过序列化后会成为一个二进制数据流,该流中的数据为一系列的 Key-Value 对。如下图所示:

        采用这种 Key-Pair 结构无需使用分隔符来分割不同的 Field。对于可选的 Field,如果消息中不存在该 field,那么在最终的 Message Buffer 中就没有该 field,这些特性都有助于节约消息本身的大小。

        Key 用来标识具体的 field,在解包的时候,客户端创建一个结构对象,Protocol Buffer 从数据流中读取并反序列化数据,并根据 Key 就可以知道相应的 Value 应该对应于结构体中的哪一个 field。

        而Key也是由以下两部分组成

        Key 的定义如下:

        | 1 | (field_number << 3) | wire_type |

        可以看到 Key 由两部分组成。第一部分是 field_number。第二部分为 wire_type。表示 Value 的传输类型。

        一个字节的低3位表示数据类型,其它位则表示字段序号。

        Wire Type 可能的类型如下表所示:

        在我们的例子当中,field id 所采用的数据类型为 int,因此对应的 wire type 为 0。细心的读者或许会看到在 Type 0 所能表示的数据类型中有 int 和 sint 这两个非常类似的数据类型。Google Protocol Buffer 区别它们的主要意图也是为了减少 encoding 后的字节数。

        每个数据头同样采用bits方式,一般1个字节就足够了,

        本例中字段a 的序号是1

        如上创建了 Test1 的结构并且把 a 的值设为 2,序列化后的二进制数据为

00

        Key 部分是

        value 部分是 , 其中字节最高位是结束标识位,即进制的2,我们在转换的时候统一将符号位转为0即可。

        协议规定数据头的低3位表示wire_type, 其它字段表示字段序号field_number,因此

       

        _ # 去掉结束标识符位

        _ # 表示数据类型, 这里是Varint

        _ # 这四位表示字段序号

        /linux/l-cn-gpb/

        原文: /archives/