• protobuf 基本使用


    proto 文件格式

     syntax = "proto3";              // 指定版本信息,不指定会报错
     packag pb;                      // 后期生成go文件的包名
     // message为关键字,作用为定义一种消息类型
     message Person{
         string name = 1;   // 名字
         int32  age = 2 ;   // 年龄
     }
     ​
     enum test{
         int32 age = 0;
     }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11

    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. 常见使用方法
      #include "person.pb.h"
      #include 
      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;
      }
      
      • 1
      • 2
      • 3
      • 4
      • 5
      • 6
      • 7
      • 8
      • 9
      • 10
      • 11
      • 12
      • 13
      • 14
      • 15
      • 16
      • 17
      • 18
      • 19
      • 20
      • 21
      • 22
      • 23
      • 24
      • 25
      • 26
      • 27
      • 28
      • 29
      • 30
      • 31
      • 32
      • 33
      • 34
      • 35
      • 36
      • 37
      • 38
      • 39
      • 40
      • 41
      • 42
      • 43
      • 44
      • 45
      • 46
      • 47
      • 48
    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. 常见使用
      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)
      
      • 1
      • 2
      • 3
      • 4
      • 5
      • 6
      • 7
      • 8
      • 9
      • 10
      • 11

    常见C++报错一:

    terminate called after throwing an instance of 'std::system_error'
      what():  Unknown error -1
    Aborted (core dumped)
    
    • 1
    • 2
    • 3

    参考文档
    解决方案

    # 增加参数 -pthread
    g++ test.cpp person.pb.cc -lprotobuf -pthread
    
    • 1
    • 2
  • 相关阅读:
    Linux下lsof命令使用
    二、Linux 文件与目录结构、VI/VIM 编辑器(重要)
    【Java】恺撒密码,stream流,方法引用
    Failed to rollback to checkpoint/savepoint hdfs://mycluster:8020/ck/sapgateway
    第四章 图表样式美化
    腾讯面试——机器学习/算法面试案例集
    Qt5开发从入门到精通——终章、数据库基本概念(后续篇章升级为 QT常规应用开发)
    linux安全--日志服务器建立实验
    mysql 学习笔记-窗口函数之序号函数
    UnitTesting 单元测试
  • 原文地址:https://blog.csdn.net/m0_56306892/article/details/134284844