Protobuf知识点和常用方法

526 阅读6分钟

知识点

google::protobuf::Message

所有的 Protocol Buffers(protobuf)数据结构都继承自 google::protobuf::Message(下面简写为Message

Message提供了很多好用的成员函数:

  1. SerializeToString() / SerializeToArray()

    • SerializeToString(string* output):将消息序列化为字符串,并存储在指定的 output 字符串中。
    • SerializeToArray(void* data, int size):将消息序列化为字节数组,并存储在指定的数据区域中。
  2. ParseFromString() / ParseFromArray()

    • ParseFromString(const string& data):从字符串中解析消息的内容。
    • ParseFromArray(const void* data, int size):从字节数组中解析消息的内容。
  3. ByteSizeLong()

    • ByteSizeLong():返回消息序列化后的字节大小,以 int64_t 类型表示。
  4. SerializeToOstream() / ParseFromIstream()

    • SerializeToOstream(ostream* output_stream):将消息序列化到给定的输出流中。
    • ParseFromIstream(istream* input_stream):从输入流中解析消息的内容。
  5. CopyFrom()

    • CopyFrom(const Message& from):从另一个消息对象复制内容到当前消息对象。
  6. MergeFrom()

    • MergeFrom(const Message& from):合并另一个消息对象的内容到当前消息对象,用于合并部分更新的消息。
  7. Clear()

    • Clear():清除消息的所有字段值,将消息重置为空状态。
  8. GetDescriptor()

    • GetDescriptor():获取消息类型的描述符,用于动态获取消息结构信息。

Descriptor

通过Message的GetDescriptor()函数获得GetDescriptor() 方法返回一个指向消息类型描述符(google::protobuf::Descriptor)的指针,描述符包含有关消息类型的元数据,如字段名称、字段编号、字段类型等。这对于在运行时获取消息结构信息非常有用。

FiledDescriptor

通过Descriptor的field(int index)可以获取消息类型的第 index 个字段的描述符。 google::protobuf::FieldDescriptor 类是 Protocol Buffers 中用于描述消息类型的字段的类,提供了一些常用的方法,这些方法允许在运行时获取关于字段的各种信息,如名称、类型、编号、标签等。这对于动态操作 Protocol Buffers 消息的字段非常有用。

Reflection

google::protobuf::Reflection 类是 Protocol Buffers 中的一个重要类,它提供了在运行时对消息进行反射操作的方法。通过 Reflection,你可以动态地访问和修改消息的字段值,而无需事先知道消息的具体类型。

常用方法

Descriptor

Descriptor提供了如下常用方法:

  1. full_name()

    • const std::string& full_name() const:返回消息类型的全名(包括命名空间)。
  2. name()

    • const std::string& name() const:返回消息类型的简短名称(不包括命名空间)。
  3. field_count()

    • int field_count() const:返回消息类型包含的字段数量。
  4. field(int index)

    • const FieldDescriptor* field(int index) const:返回消息类型的第 index 个字段的描述符。
  5. FindFieldByName(const std::string& name)

    • const FieldDescriptor* FindFieldByName(const std::string& name) const:根据字段名称查找字段的描述符,如果找不到则返回 nullptr
  6. FindFieldByNumber(int number)

    • const FieldDescriptor* FindFieldByNumber(int number) const:根据字段编号查找字段的描述符,如果找不到则返回 nullptr
  7. FindOneofByName(const std::string& name)

    • const OneofDescriptor* FindOneofByName(const std::string& name) const:根据 Oneof 名称查找 Oneof 的描述符,如果找不到则返回 nullptr
  8. is_extendable()

    • bool is_extendable() const:返回消息类型是否可以被扩展。
  9. extension_count()

    • int extension_count() const:返回消息类型包含的扩展字段数量。
  10. extension(int index)

    • const FieldDescriptor* extension(int index) const:返回消息类型的第 index 个扩展字段的描述符。

FiledDescriptor

  1. name()

    • const std::string& name() const:返回字段的名称。
  2. full_name()

    • const std::string& full_name() const:返回字段的全名(包括消息类型的命名空间)。
  3. number()

    • int number() const:返回字段的编号。
  4. type()

    • CppType type() const:返回字段的类型,使用 CppType 枚举表示。
    1. TYPE_DOUBLE:双精度浮点数
    2. TYPE_FLOAT:单精度浮点数
    3. TYPE_INT64:64位整数
    4. TYPE_UINT64:64位无符号整数
    5. TYPE_INT32:32位整数
    6. TYPE_FIXED64:64位固定大小整数
    7. TYPE_FIXED32:32位固定大小整数
    8. TYPE_BOOL:布尔值
    9. TYPE_STRING:字符串
    10. TYPE_GROUP:(不再使用)
    11. TYPE_MESSAGE:嵌套消息
    12. TYPE_BYTES:字节数组
    13. TYPE_UINT32:32位无符号整数
    14. TYPE_ENUM:枚举类型
  5. label()

    • Label label() const:返回字段的标签,使用 Label 枚举表示,可能是 LABEL_REQUIREDLABEL_OPTIONALLABEL_REPEATED
  6. is_required()

    • bool is_required() const:返回字段是否为必需字段(LABEL_REQUIRED)。
  7. is_optional()

    • bool is_optional() const:返回字段是否为可选字段(LABEL_OPTIONAL)。
  8. is_repeated()

    • bool is_repeated() const:返回字段是否为重复字段(LABEL_REPEATED)。
  9. message_type()

    • const Descriptor* message_type() const:如果字段类型是消息类型,返回消息类型的描述符;否则返回 nullptr
  10. enum_type()

    • const EnumDescriptor* enum_type() const:如果字段类型是枚举类型,返回枚举类型的描述符;否则返回 nullptr
  11. containing_type()

    • const Descriptor* containing_type() const:返回包含该字段的消息类型的描述符。
  12. default_value()

    • const std::string& default_value() const:返回字段的默认值的字符串表示。
  13. is_extension()

    • bool is_extension() const:返回字段是否为扩展字段。
  14. extension_scope()

    • const Descriptor* extension_scope() const:如果字段是扩展字段,则返回扩展字段的作用域(定义该扩展字段的消息类型)的描述符。

Reflection

GetReflection() 方法返回一个消息类型的反射对象,可以通过该对象进行动态访问修改消息的字段值。这对于编写通用的代码以处理未知消息类型非常有用。

  1. GetDescriptor()

    • const Descriptor* GetDescriptor() const:返回与该反射对象关联的消息类型的描述符。
  2. GetInt32() / GetUInt32() / GetInt64() / GetUInt64() / GetFloat() / GetDouble() / GetString() / GetBool() / GetEnum()

    • 以上方法用于获取相应类型的字段值。方法的参数包括消息对象、字段描述符以及(在某些情况下)枚举值的描述符。
  3. SetInt32() / SetUInt32() / SetInt64() / SetUInt64() / SetFloat() / SetDouble() / SetString() / SetBool() / SetEnum()

    • 以上方法用于设置相应类型的字段值。方法的参数包括消息对象、字段描述符以及要设置的值。
  4. GetRepeatedInt32() / GetRepeatedUInt32() / GetRepeatedInt64() / GetRepeatedUInt64() / GetRepeatedFloat() / GetRepeatedDouble() / GetRepeatedString() / GetRepeatedBool() / GetRepeatedEnum()

    • 以上方法用于获取重复字段中相应类型的所有值。
  5. SetRepeatedInt32() / SetRepeatedUInt32() / SetRepeatedInt64() / SetRepeatedUInt64() / SetRepeatedFloat() / SetRepeatedDouble() / SetRepeatedString() / SetRepeatedBool() / SetRepeatedEnum()

    • 以上方法用于设置重复字段中相应类型的所有值。
  6. AddInt32() / AddUInt32() / AddInt64() / AddUInt64() / AddFloat() / AddDouble() / AddString() / AddBool() / AddEnum()

    • 以上方法用于向重复字段中添加相应类型的值。
  7. ClearField()

    • void ClearField(const FieldDescriptor* field):清除单个字段的值。
  8. ClearRepeatedField()

    • void ClearRepeatedField(const FieldDescriptor* field):清除重复字段的所有值。
  9. ListFields()

    • void ListFields(const Message& message, std::vector<const FieldDescriptor*>* output) const:获取消息中所有非默认值字段的描述符,并将其存储在输出向量中。
  10. HasField()

    • bool HasField(const Message& message, const FieldDescriptor* field) const:检查消息中是否存在某个字段的值。
  11. HasRepeatedField()

    • bool HasRepeatedField(const Message& message, const FieldDescriptor* field) const:检查消息中是否存在某个重复字段的值。
  12. GetUnknownFields()

    • const UnknownFieldSet& GetUnknownFields(const Message& message) const:获取消息中未知字段的集合。