赞
踩
1、概念
Protocol Buffers 是一种轻便高效的结构化数据存储格式,可以用于结构化数据串行化,或者说序列化。它很适合做数据存储或 RPC 数据交换格式。可用于通讯协议、数据存储等领域的语言无关、平台无关、可扩展的序列化结构数据格式。
将 程序数据转化成能被存储并传输的格式的过程被称为“序列化”(Serialization),而它的逆过程则可被称为“反序列化” (Deserialization)。
简单来说,序列化就是将对象实例的状态转换为可保持或传输的格式的过程。与序列化相对的是反序列化,它根据流重构对象。这两个过程结合起来,可以轻 松地存储和传输数据。
序列化:将对象变成字节流的形式传出去。 反序列化:从字节流恢复成原来的对象。
Message:Person是自定义的pb类型,继承自Message. MessageLite作为Message基类,更加轻量级一些。
通过Message的两个接口GetDescriptor/GetReflection
,可以获取该类型对应的Descriptor/Reflection。
Descriptor:Descriptor是对message类型定义的描述,包括message的名字、所有字段的描述、原始的proto文件内容等,提供的接口:获取所有字段的个数:int field_count() const
获取单个字段描述类型FieldDescriptor
的接口 。
FieldDescriptor:描述message中的单个字段,例如字段名,字段属性(optional/required/repeated)等。
Reflection:提供了动态读写pb字段的接口,对pb对象的自动读写主要通过该类完成。对每种类型,Reflection都提供了一个单独的接口用于读写字段对应的值。
- //读操作
- virtual int32 GetInt32 (const Message& message,const FieldDescriptor* field) const = 0;
-
- virtual int64 GetInt64 (const Message& message,const FieldDescriptor* field) const = 0;
-
- //对于枚举和嵌套的message
-
- virtual const EnumValueDescriptor* GetEnum(const Message& message, const FieldDescriptor* field) const = 0;
-
- virtual const Message& GetMessage(const Message& message,const FieldDescriptor* field,MessageFactory* factory = NULL) const = 0;
反射使用
- // 先获得类型的Descriptor .
- auto descriptor = google::protobuf::DescriptorPool::generated_pool()->FindMessageTypeByName("T.Test");
- if (nullptr == descriptor)
- {
- return 0 ;
- }
- // 利用Descriptor拿到类型注册的instance. 这个是不可修改的.
- auto prototype = google::protobuf::MessageFactory::generated_factory()->GetPrototype(descriptor);
- if ( nullptr == descriptor)
- {
- return 0 ;
- }
- // 构造一个可用的消息.
- auto message = prototype->New();
- // 只有当我们预先编译了test消息并且正确链接才能这么干.
- auto test = dynamic_cast<T::Test*>(message);
- // 直接调用message的具体接口
- // 其实这些接口是语法糖接口.所以并没有对应的反射机制来对应调用.
- // 反射机制实现了的Set/Get XXX系列接口,是属于Reflection的接口,接收Message作为参数.
- test->set_id(1);
- // 拿到一个对象,不在乎怎么拿到,可以是通过反射拿到。
- // 这里简单直接的创建一个.
- T::Test p_test ;
- // 拿到对象的描述包.
- auto descriptor = p_test.GetDescriptor() ;
- // 拿到对象的反射配置.
- auto reflecter = p_test.GetReflection() ;
- // 拿到属性的描述包.
- auto field = descriptor->FindFieldByName("id");
- // 设置属性的值.
- reflecter->SetInt32(&p_test , field , 5 ) ;
- // 获取属性的值.
- std::cout<<reflecter->GetInt32(p_test , f
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。