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
相关推荐
如竟没有火炬18 分钟前
全排列——交换的思想
开发语言·数据结构·python·算法·leetcode·深度优先
嵌入式小李.man31 分钟前
C++第十三篇:继承
开发语言·c++
机器瓦力35 分钟前
Trae使用:重构一个项目
python·ai编程
jarreyer1 小时前
python离线包安装方法总结
开发语言·python
码银1 小时前
【python】基于 生活方式与健康数据预测数据集(Lifestyle and Health Risk Prediction)的可视化练习,附数据集源文件。
开发语言·python·生活
kyle~2 小时前
C++---嵌套类型(Nested Types)封装与泛型的基石
开发语言·c++·算法
星期天要睡觉2 小时前
大模型(Large Language Model, LLM)——什么是大模型,大模型的基本原理、架构、流程
人工智能·python·ai·语言模型
Q_Q19632884753 小时前
python+uniapp基于微信美食点餐系统小程序
spring boot·python·微信·django·flask·uni-app·node.js
KIKIiiiiiiii3 小时前
微信个人号开发中如何高效实现API二次开发
java·前端·python·微信