protobuf 基本使用

proto 文件格式

protobuf 复制代码
 syntax = "proto3";              // 指定版本信息,不指定会报错
 packag pb;                      // 后期生成go文件的包名
 // message为关键字,作用为定义一种消息类型
 message Person{
     string name = 1;   // 名字
     int32  age = 2 ;   // 年龄
 }
 ​
 enum test{
     int32 age = 0;
 }

protobuf 和 C++

  1. 没有设置默认值,也会有默认值,例如:布尔类型(bool)默认为 false。

  2. 定义类型,唯一的标识符,范围为1到2^29 - 1

  3. 导入头文件,首先是包名作为namespace,声明变量pb::Person person;

  4. proto2中required optional repeated 必须写,不写编译不通过

  5. proto3中只有repeated可用,写了其他的,编译不通过

  6. required:必须包含
    optional:可选包含
    repeated:可以重复包含

  7. 若required写了,在序列化时候,会报错

  8. 常见使用方法

    cpp 复制代码
    #include "person.pb.h"
    #include <iostream>
    using namespace std;
    
    
    int main() {
        // 创建一个 Person 对象并设置其字段
        pb::Person person;
        // 设置值,方式一
        person.set_name("chang");
        cout << person.name() << endl; 
    
        // 设置值,方式二
        person.mutable_name()->assign("jiang");
        cout << person.name() << endl; 
    
        // 设置值,方式三
        pb::Person person1;
        person.CopyFrom(person1);
        person.mutable_name()->assign("da");
        cout << person.name() << endl; 
    
        // 如果是消息体嵌套,方式一
        pb::Person::Student* student2 = person.add_s();
        student2->set_id("fef");
    
        student2 = person.add_s();
        student2->set_id("fef");
    
        cout << person.s_size() << endl;
        cout << person.s(0).id() << endl; 
        cout << person.s(1).id() << endl; 
    
        // 如果是消息体嵌套,方式二
        person.add_s();
        person.mutable_s(2)->set_id("e2");
        cout << person.s_size() << endl;
        cout << person.s(2).id() << endl; 
    
        // 序列化
        std::string serialized_data;
        person.SerializeToString(&serialized_data);
    
        // 反序列化
        pb::Person new_person;
        new_person.ParseFromString(serialized_data);
        return 0;
    }
  9. proto编译成c++,protoc --cpp_out=./ ./demo.proto

  10. c++编译成执行文件g++ test.cpp person.pb.cc -lprotobuf -pthread

protobuf 和 python

  1. 编译方式:protoc --python_out=./ person.proto

  2. 常见使用

    python 复制代码
    import person_pb2            # 直接导入编译好的文件
    p =  person_pb2.Person()     # 直接使用message类
    p.name = "fwef"
    print(p.name)
    
    # 将消息序列化为字节串
    serialized_data = p.SerializeToString()
    
    # 将字节串反序列化为消息对象
    new_person = person_pb2.Person()
    new_person.ParseFromString(serialized_data)

常见C++报错一:

bash 复制代码
terminate called after throwing an instance of 'std::system_error'
  what():  Unknown error -1
Aborted (core dumped)

参考文档

解决方案:

bash 复制代码
# 增加参数 -pthread
g++ test.cpp person.pb.cc -lprotobuf -pthread
相关推荐
30955666613 分钟前
股票接口返回 404 与空数组的排查笔记:证书状态与级别参数
java·笔记·python·ios·iphone·股票数据api·股票数据接口
2601_9679801136 分钟前
世界上最好的Python编辑器是什么?我投PyCharm一票
ide·python·pycharm·数据科学·jupyter notebook
晴天的雨.9921 小时前
【C++】继承篇
java·开发语言·c++
wuyk5551 小时前
Spider-第09讲-三格式落盘CSV-Excel-JSON
爬虫·python·json·excel
青少儿编程课堂1 小时前
蓝桥杯青少组图形化 + 全国青少年信息素养大赛 + 电子学会图形化考级:校园大富翁经营闯关解析
c++·python·算法·bfs·信息学竞赛
another heaven1 小时前
【C/C++ 第一次跨越(上):用 C++11/14 停止制造新的旧代码】
c语言·c++·制造
qq_406981031 小时前
c++ lamda(三)Lambda表达式
java·前端·c++
特立独行的猫A7 小时前
用仓颉语言 cj-tauri 框架,五分钟给娃做了个鸿蒙形近字游戏
java·后端·python
大可不必了12 小时前
03 函数定义和调用
开发语言·python
I_belong_to_jesus12 小时前
C++关于分支预测的优化1
开发语言·c++·算法