zoukankan      html  css  js  c++  java
  • Google Protobuf扩展字段使用

    背景说明

    Google Protobuf中不支持数据结构的派生关系,因此,如果在存在派生体系的对象中定义数据结构时,通过组合方式对数据结构进行组合,则需要对基类对象提供的通用接口进行重载或在外部进行动态转型才能达到获取或设置数据的目的。

    因此考虑使用Google Protobuf提供的extension扩展机制解决数据结构之间的不能派生的问题,以此来达到减少重复工作量和便于维护代码的目的。

    使用说明

    1. 定义公共数据类型

      描述:

      此数据类型为对象派生体系同基类提供的公共数据类型

      示例:

       
      1 // 公共数据类型
      2 message BaseDataType
      3 {
      4     extensions 100 to max;   //标识此字段可扩展,此处可指定扩展字段的ID有效范围,to max表示字段范围至最大值
      5     optional string BaseField1 = 1;
      6     optional string BaseField2= 2;
      7     ...
      8 } 
      View Code
    2. 定义扩展数据类型

      描述:

      此数据类型为对象派生体系中派生类使用的数据类型

      示例:

       1 message ChildDataType
       2 {
       3     extend BaseDataType
       4     {
       5         optional ChildDataType ChildData = 100;     // 将子数据类型整体扩展至公共数据中
       6         optional int32  ExtendValue = 101;          // 扩展具体数据类型
       7     }
       8     optional string ChildField1 = 1;
       9     optional string ChildField2= 2;
      10     ...
      11 } 
      View Code
       
    3. 初始化数据类型

      描述:

      公共数据类型与普通数据类型使用相同,此处仅说明扩展数据类型使用方法

      示例:

       
       1 // 对象基类
       2 class BaseClass
       3 {
       4     public BaseClass()
       5     {
       6          m_pData = new BaseDataType();
       7     }
       8 public:
       9     Message* m_pData;
      10 };
      11  
      12 // 对象派生类
      13 class ChildClass : public BaseClass
      14 {
      15     public ChildClass ()
      16     {
      17         BaseDataType * pBaseData = new BaseDataType();
      18         // 创建爱你扩展数据类型
      19         ChildDataType* pChildData = pBaseData->MutableExtension(ChildDataType::ChildData);
      20         //初始化数据
      21         pChildData-> set_childfield1("123");
      22         pBaseData->SetExtension(ChildDataType::ExtendValue, 123);
      23     }
      24 }; 
      View Code
    4. 使用数据类型

      描述:

      通过HasExtension、GetExtension、MutableExtension来访问数据;

      示例:

      1 // 构造对象访问扩展数据类型数据
      2 BaseClass* pBaseObj = new ChildClass();
      3 BaseDataType* pBaseData = dynamic_cast<BaseDataType*>(pBaseObj->m_pData);
      4 assert(pBaseData->HasExtension(ChildDataType::ChildData));
      5 // 获取扩展数据
      6 const ChildDataType& childdata = pBaseData->GetExtension(ChildDataType::ChildData);
      7 int value = pBaseData->GetExtension(ChildDataType::ExtendValue); 
      View Code
    5. 数据复制及传输

      描述:

      C++代码中数据复制及传输解析与普通数据类型相同,此处仅说明C#代码中需要注意事项。

      C#中通过ParseFrom进行字节数据转换时,需要传入对扩展数据结构的说明信息ExtensionRegistry,否则扩展数据字段将作为未知数据处理。

      示例:

       1 // 构造扩展数据类型
       2 ChildDataType.Builder childdata = new ChildDataType.Builder();
       3 childdata.ChildField1 = "123";
       4 // 构造公共数据类型
       5 BaseDataType.Builder basedata = new BaseDataType.Builder();
       6 basedata.SetExtension(ChildDataType.ChildData,
       7 childdata.Build());
       8  
       9 // 转换至字节数据数据
      10 byte[] buf = basedata.Build().ToByteArray();
      11  
      12 // 创建扩展字段信息
      13 ExtensionRegistry registry = ExtensionRegistry.CreateInstance();
      14 registry.Add(ChildDataType.ChildData);
      15 registry.Add(ChildDataType.ExtendValue);
      16  
      17 // 从字节数据转换
      18 BaseDataType basedataCopy = BaseDataType.ParseFrom(buf, registry);
      19 System.Diagnostics.Debug.Assert(basedataCopy.HasExtension(ChildDataType.ChildData)); 
      View Code
  • 相关阅读:
    ajax如何向后台传递数组,在后台该如何接收的问题(项目积累)
    循环读取list 的几种方法?
    jQuery里$(this)和this的区别在哪?
    Hibernate多对多双向关联需要注意的问题(实例说话)
    window.open()用法说明
    struts2 跳转类型 result type=chain、dispatcher、redirect(redirect-action)
    页面中的删除确认(ajax)、输入框中确认信息是否可用(ajax)的jquery代码
    理解ValueStack的基本机制 OGNL表达式
    Struts2中的ModelDriven机制及其运用
    mySQl数据库中不能插入中文的处理办法
  • 原文地址:https://www.cnblogs.com/rain2012qf/p/4241020.html
Copyright © 2011-2022 走看看