【Protobuf速成指南】Any类型的使用

文章目录

  • 2.2 Any类型的使用
    • 一、基本认识
    • 二、使用需知
    • 三、Any字段的使用
      • ①修改proto文件
      • ② Any相关函数
      • ③ 类型转换
    • 四、Contact 2.2 改写

2.2 Any类型的使用

 本系列文章将通过对通讯录项目的不断完善,带大家由浅入深的学习Protobuf的使用。这是Contacts的2.2版本,在这篇文章中将带大家学习Protobuf的 Any 类型语法,并将其用到我们的项目中

一、基本认识

 Protobuf中的Any类型可以理解为泛型类型,它可以存储任何消息类型的字段(int, char等类型必须先封装成消息类型)。Any类型字段也可以用 Repeated 修饰。

 Any类型定义在 any.proto 文件中。可以在 /usr/local 路径下可以找到。我在安装的时候将 lib 和 include 统一配置到 /usr/local/protobuf 文件中。如果没有配置的话,lib和include是分散的。

【Protobuf速成指南】Any类型的使用_第1张图片

二、使用需知

①头文件的包含:

image-20230608113635069

使用Any字段前首先需要包含头文件,先前做过的环境变量配置如上

  • 因此可以如下包含头文件

    image-20230608113832834

  • 引入 any.proto 文件

    image-20230608115147745

②命名空间:gooole::protobuf

image-20230608114030513

三、Any字段的使用

①修改proto文件

我们先创建一个Address消息字段,并在 PeopleInfo 消息中用Any类型字段接收

syntax = "proto3";
package contact2;

import "google/protobuf/any.proto";

message Address{
    string home = 1;
    string company = 2;
}

message PeopleInfo{
    string name = 1;
    int32 age = 2;
    message Phone{   
        string number = 1;
        enum PhoneType{
            MOBILE = 0;
            FIXED = 1;
        }
        PhoneType type = 2;
    }
    repeated Phone phone = 3;
    google.protobuf.Any addr = 4;
}

message Contact{
    repeated PeopleInfo contact = 1;
}

② Any相关函数

编译 .proto 文件后,我们来分析 contacts.pb.h 文件中对于Any类型更新的代码片段

// [作用]:判断Any字段addr是否被设置
bool has_addr() const;


// [作用]:清除对Any字段的设置(重置为默认值)
void clear_addr();


// [作用]:返回Any字段的内容
const ::PROTOBUF_NAMESPACE_ID::Any& addr() const;


// [作用]:用于获取Any消息中的 addr 成员变量,并返回一个指向 addr 的指针,可以通过这个指针修改该Any对象中 addr
::PROTOBUF_NAMESPACE_ID::Any* mutable_addr();
// [注意]:在使用 mutable_addr() 方法获取指针之前,需要确定该 Any 字段中存储的值已经被正确地解析为具体的类型,否则直接使用 mutable_addr() 可能会导致程序崩溃或者其他不可预知的问题


 // [作用]:释放 Any 对象中包含的数据(Any字段里的内容被重置为默认值),并返回一个指向释放数据的指针。也就是将该对象的所有权转移给调用方
 PROTOBUF_NODISCARD ::PROTOBUF_NAMESPACE_ID::Any* release_addr();
// [注意]:该方法所释放的是 Any 类型对象中存储的对象的所有权,而非 Any 类型对象本身的所有权。

③ 类型转换

 前面提到,Any字段中可以存储任意消息类型,这就要涉及到任意消息类型和Any类型的互转。这部分代码就在Google为我们写好的头文件 any.pb.h 中。

// 将任意消息类型转为Any类型
bool PackFrom(const ::PROTOBUF_NAMESPACE_ID::Message& message)
    
// 将Any类型转为任意消息类型
bool UnpackTo(::PROTOBUF_NAMESPACE_ID::Message* message) const
    
// 判断 Any 字段存储的对象类型是否为 T
template<typename T> bool Is() const

四、Contact 2.2 改写

write.cc:
【Protobuf速成指南】Any类型的使用_第2张图片

read.cc:

【Protobuf速成指南】Any类型的使用_第3张图片

区分下面的写法:

image-20230609171944727

[说明]:

  • 正确:addr返回的是const对象。const对象才能调用const修改的函数
  • 错误:mutable_addr的对象是可以修改

image-20230609171849058

【Protobuf速成指南】Any类型的使用_第4张图片

你可能感兴趣的:(【Protobuf速成教程】,Protobuf,C++)