Protobuf C++ API 简介

本文是一篇译文,原文为C++ API

descriptor.h

#include <google/protobuf/descriptor.h>
namespace google::protobuf

这个文件包含了描述protocol message类型信息的类。

关键类有:

  • Descriptor:描述protocol message的类型信息
  • FieldDescriptor:描述message的某个字段
  • DescriptorPool:创建desciptors

你可以使用消息的desciptor,从而在运行时了解该消息包含哪些字段以及这些字段的类型。 Message接口还允许您通过传递您感兴趣的字段的FieldDescriptor来动态访问和修改单个字段。

class Descriptor

#include <google/protobuf/descriptor.h>
namespace google::protobuf

descriptor描述了protocol message的类型信息。可以通过调用Message::GetDescriptor()来获取给定的消息对象的描述符。编译器protoc产生的消息类也有一个名为descriptor()的静态函数可以返回该消息的描述符。我们也可以用DescriptorPool来创建自己的描述符。

Descriptor的主要函数有:

成员函数 描述
const string & name() const 消息的类型名,不包含它的作用域
const string & full_name() const 消息类型的完全限定名称,如bar.Foo.Baz
int index() const 该描述符在文件或包含类型的消息类型数组中的索引。
const MessageOptions & options() const 获取此消息类型的选项。
int field_count() const 此消息类型中的字段数。
const FieldDescriptor * field(int index) const 按索引获取字段,其中0 <= index <field_count()。
它们按照.proto文件中定义的顺序返回。
const FieldDescriptor *
FindFieldByNumber(int number) const
按声明的标识号查找字段。如果不存在此类字段,则返回NULL。
const FieldDescriptor *
FindFieldByName(const string & name) const
按名称查找字段。 如果不存在此类字段,则返回NULL。

class FieldDescriptor

#include <google/protobuf/descriptor.h>
namespace google::protobuf

FieldDescriptor描述了message的某个字段。为了获取给定字段的描述符,首先获取定义该字段的消息的描述符,然后调用Descriptor::FindFieldByName()

class DescriptorPool

#include <google/protobuf/descriptor.h>
namespace google::protobuf

用来创建描述符。

通常情况下,我们不希望构建自己的描述符。协议编译器构造的消息类会为我们提供。但是,如果我们正在自己实现Message,或者我们正在编写一个可以运行于任意数据类型上并且需要从某种数据库加载这些数据类型的程序,我们可能就需要构建自己的描述符。

由于描述符由大量交叉链接的数据组成,这些数据很难手动组合在一起,因此提供了DescriptorPool以简化过程。它可以采用FileDescriptorProto(在descriptor.proto中定义),验证它,并将其转换为一组很好的交叉链接描述符。

DescriptorPool还有助于内存管理。描述符由许多包含静态数据和指针的对象组成。当需要删除此数据时,我们很可能需要立即删除所有数据。实际上,我们希望立即删除的池中的描述符全部都是交叉链接的情况并不少见。DescriptorPool类就是这样的描述符池,它会为我们处理内存管理。

我们还可以按名称搜索DescriptorPool中的描述符,或者按编号搜索扩展名。

成员函数 描述
static const DescriptorPool *
generated_pool()
获取指向生成的描述符池的指针。
生成的协议消息类将在此池中分配其描述符。 不要将自己的描述符添加到此池中。
const Descriptor *
FindMessageTypeByName(const string & name) const
按完全限定名称查找描述符。 会查找顶级描述符和嵌套描述符。 如果找不到,则返回NULL。
const FieldDescriptor *
FindFieldByName(const string & name) const
按完全限定名称查找描述符。 会查找顶级描述符和嵌套描述符。 如果找不到,则返回NULL。

给出一个使用desciptor的例子。假设有一个消息的定义为:

message Foo {
  optional string text = 1;
  repeated int32 numbers = 2;
}

然后我们用protoc编译器生成了相应的类,我们可以这样使用该类:

string data;  // Will store a serialized version of the message.

{
   
  // Create a message and serialize it.
  Foo foo;
  foo.set_text("Hello World!");
  foo.add_numbers(1);
  foo.add_numbers(5);
  foo.add_numbers(42);

  foo.Seriali
  • 1
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值