Google Protocol Buffer

让人想犯罪 __ 提交于 2020-03-09 08:29:41

ProtoBuf使用步骤:

  • 在.proto文件中指定需要序列化的消息格式;
  • 使用protocol buffer编译器将.proto文件生成你所需语言的数据访问类;
  • 然后就可以在自己的程序中使用这些类。

ProtoBuf相较于XML的优势:

  • 简单
  • 3到10倍地小
  • 20到100倍地快
  • 更明确
  • 生成的数据访问类更容易供编程使用

劣势:

  • 不适合处理标记文本(HTML)
  • 不可读

 ProtoBuf 生成的c++代码

  • packages
    • .proto文件中package声明相当于C++中namespace
  • messages
    • message Foo {}

       message Foo会生成一个类Foo,该类继承自google::protobuf::Message。根据优化模式来确定是否重载Message中的虚函数(纯虚函数一定会实现)。默认情况下,为了获得最大执行速度,会实现所有方法,但是如果.proto文件包含:

    • option optimize_for = CODE_SIZE;

       只会重载必要的方法,这会显著减少生成代码的大小,但是会降低效率。如果.proto文件包含:

    • option optimize_for = LITE_RUNTIME;

       进行所有方法的快速实现,但是只实现google::protobuf::MessageLite接口,该接口只有Message中的部分方法。

    • Message接口定义的方法:
      • Foo():默认构造函数
      • ~Foo():默认析构函数
      • Foo(const Foo& other):复制构造函数
      • Foo& operator=(const Foo& other):赋值操作符
      • void Swap(Foo* other):与另一个消息交换内容
      • const UnknownFieldSet& unknown_fields() const:返回处理消息过程中遇到的未知域set
      • UnknownFieldSet* mutable_unknown_fields():返回未知域set的可变指针
  • Fields 
  • optional int32 foo_bar = 5;
     会生成常量:
    static const int kFooBarFieldNumber = 5;
  • Singular Numeric Fields
    • 对于下面的任何一个定义
    • optional int32 foo = 1;
      required int32 foo = 1;

       编译器都会生成下面的接口方法;

    • bool has_foo() const:判断foo这个域有没有被设置
    • int32 foo() const:返回foo域的当前值,如果该域没有被赋值,则返回默认值。
    • void set_foo(int32 value):设置foo域的值
    • void clear_foo():清除foo域的值。
  • Singular String Fields
    • 对于下面的任何一个定义
    • optional string foo = 1;
      required string foo = 1;
      optional bytes foo = 1;
      required bytes foo = 1;

       编译器都会生成下面的接口方法:

    • bool has_foo() const:判断foo域有没有被赋值
    • const string& foo() const:返回foo域的当前值。
    • void set_foo(const string& value):设置foo域的值为value。
    • void set_foo(const char* value):通过C类型的字符串赋值。
    • void set_foo(const char* value, int size):赋值指定长度的串。
    • string* mutable_foo():返回指向串的指针。
    • void clear_foo():清除域。
    • void set_allocated_foo(string* value):赋值string对象,如果原先域有值则释放。
    • string* release_foo():释放该域的所有权,并返回指向string对象的指针。再调用该函数后,调用者拥有分配的string对象的所有权,has_foo()会返回false,foo()会返回默认值。

  • Singular Enum Fields
    • 对于枚举类型:
    • enum Bar {
        BAR_VALUE = 1;
      }

       对于下面的任何一个定义:

    • optional Bar foo = 1;
      required Bar foo = 1;

       编译器都会生成下面的方法:

    • bool has_foo() const:判断foo域有没有被赋值。
    • Bar foo() const:返回域的当前值。
    • void set_foo(Bar value):设定域的值
    • void clear_foo():清除域的值。
  • Singular Embedded Message Fields
    • 对于如下定义:
    • optional Bar foo = 1;
      required Bar foo = 1;

       编译器会生成方法:

    • bool has_foo() const:
    • const Bar& foo() const:
    • Bar* mutable_foo():
    • void clear_foo():
    • void set_allocated_foo(Bar* bar):
    • Bar* release_foo():
  • Repeated Numeric Fields
    • 对于定义:
    • repeated int32 foo = 1;

       编译器会生成如下方法:

    • int foo_size() const:返回该域中元素的个数。
    • int32 foo(int index) const:根据下标返回对应值。
    • void set_foo(int index, int32 value):设置指定下标的值。
    • void add_foo(int32 value):在域新增一个值。
    • void clear_foo():清除域中所有值。
    • const RepeatedField<int32>& foo() const:
    • RepeatedField<int32>* mutable_foo():

 

 

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!