当前位置:首页 » 《休闲阅读》 » 正文

快速认识和上手Protobuf

14 人参与  2024年11月21日 12:05  分类 : 《休闲阅读》  评论

点击全文阅读


Protobuf

ProtoBuf(全称Protocol Buffer)是数据结构序列化和反序列化框架(谷歌开发)
它具有以下特点:

语⾔⽆关、平台⽆关:即 ProtoBuf ⽀持 Java、C++、Python 等多种语⾔,⽀持多个平台⾼效:即⽐ XML (数据交换格式)更⼩、更快、更为简单扩展性、兼容性好:你可以更新数据结构,⽽不影响和破坏原有的旧程序(根据我们的需要自己生成需要的结构)

使用方法

编写的.proto文件,自定义结构对象及属性内容(描述对象中,有什么样的成员,每个成员具有什么样的属性。比如描述学生结构:姓名:字符串、学号:长整形、。。。)编译proto文件:使用protoc编译器编译.proto文件中的描述,生成对应的接口代码,存放在新生成头文件和源文件中。 .h 中定义了我们所描述的数据结构对象类;.cc定义实现了结构化对象的访问&操作&序列化&反序列化 使用:引入生成的头文件,在代码中根据需要使用即可。依赖⽣成的接⼝,将编译⽣成的头⽂件包含进我们的代码中,实现对. proto ⽂件中定义的字段进⾏设置和获取,和对 message 对象进⾏序列化和反序列化

编写的.proto文件

.proto文件规范:

创建.proto⽂件时,⽂件命名应该使⽤全⼩写字⺟命名 ,多个字⺟之间⽤_ 连接。例如:lower_snake_case.proto书写.proto⽂件代码时,应使⽤2个空格的缩进(推荐而已不强制)

语法规则:

必须写:

1. 指定proto3语法(声明语法版本):
syntax = "proto3";
2. package声明符(声明命名空名称):
相当于命名空间,避免我们定义的消息出现冲突
package 根据情况命名 package contacts;
3. 定义结构化对象描述(定义结构化对象描述)
可以理解为类

message 消息类型名{各个字段描述: 字段类型 字段名 = 字段唯一编号;}例:message contact{uint64 sn = 1;//学号string name = 2;//姓名float score = 3;//成绩}

其中Protobuf的类型太多了就一一列出来了,建议有需求就直接搜。

编译contacts.proto文件

编译命令行格式为:

protoc  [--proto_path=IMPORT_PATH]  --cpp_out=DST_DIR  path/to/file.proto1. protoc 是 Protocol Buffer 提供的命令⾏编译⼯具。2. --proto_path 指定 被编译的.proto⽂件所在⽬录,可多次指定。可简写成 -IIMPORT_PATH 。如不指定该参数,则在当前⽬录进⾏搜索。当某个.proto ⽂件 import 其他.proto ⽂件时,或需要编译的 .proto ⽂件不在当前⽬录下,这时就要⽤-I来指定搜索⽬录。3. --cpp_out= 指编译后的⽂件为 C++ ⽂件。4. OUT_DIR 编译后⽣成⽂件的⽬标路径。5. path/to/file.proto 要编译的.proto⽂件6. [ ] 表示可以不写例如生成c++的方法:protoc --cpp_out=.  contacts.proto

实操 protoc编译.proto文件(附图 也可以直接看这快速了解):

编写.proto文件:
//声明proto语法版本syntax = "proto3";package contacts;message Contact{    uint64 sn = 1;    string name = 2;    float score = 3;}

在这里插入图片描述
2. 编译.proto文件

protoc --cpp_out=. contacts.proto1. protoc必备2. --cpp_out:表示生成c++文件3. ‘.’:表示生成的路径(当前路径) 4. contacts.proto 要编写的proto文件)`

输出后就会生成两个文件:
在这里插入图片描述

了解生成的代码

常用接口(序列化、反序列化):

成员的get获取接口和set设置接口:
在这里插入图片描述

常用接口:

class MessageLite {public://序列化:bool SerializeToOstream(ostream* output) const; // 将序列化后数据写⼊⽂件流bool SerializeToArray(void *data, int size) const;bool SerializeToString(string* output) const;//反序列化:bool ParseFromIstream(istream* input); // 从流中读取数据,再进⾏反序列化动作bool ParseFromArray(const void* data, int size);bool ParseFromString(const string& data);};

实操使用生成的文件:

创建contact类对象 conn

设置学号、姓名、成绩

序列化string str(存起来的是二进制的!)
通过conn对象的SerializeAsString函数序列化的数据

反序列化获取数据在contact stu对象中:
使用ParseFromString反序列化返回bool值

判断失败—返回-1成功—打印存在的 stu 的成员对象

创建makefile

g++编译(略)注意需要连接protobuf库(-l连接外部库)-lprotobuf
#include <iostream>#include "contacts.pb.h"#include "contacts.pb.cc"int main(){    contacts::contact conn;    conn.set_sn(251);    conn.set_name("坤坤");    conn.set_score(91);    std::string str = conn.SerializeAsString();    contacts::contact stu;    int n = stu.ParseFromString(str);    if(n == -1){        std::cout << "获取失败"<<std::endl;    }    else{        std::cout << stu.sn() << std::endl;        std::cout << stu.name() << std::endl;        std::cout << stu.score() << std::endl;    }    return 0;}

在这里插入图片描述


点击全文阅读


本文链接:http://zhangshiyu.com/post/189701.html

<< 上一篇 下一篇 >>

  • 评论(0)
  • 赞助本站

◎欢迎参与讨论,请在这里发表您的看法、交流您的观点。

关于我们 | 我要投稿 | 免责申明

Copyright © 2020-2022 ZhangShiYu.com Rights Reserved.豫ICP备2022013469号-1