Android CCodec Codec2 (四)C2Param - Ⅱ

这一篇内容我们来解答复杂参数定义过程中提出的疑问,本文有大量的模板和宏展开,请耐心阅读。

1、不含灵活数组的复杂结构体定义

DEFINE_AND_DESCRIBE_C2STRUCT和C2FIELD是不能分开的,使用时必须要按顺序依次调用这两个宏定义。宏定义比较复杂,我们以C2StoreIonUsageStruct为例直接看展开后的样子。

将DEFINE_AND_DESCRIBE_C2STRUCT(StoreIonUsage)展开变成:

    public: 
      enum : uint32_t { CORE_INDEX = kParamIndexStoreIonUsage }; 
    private: 
      const static std::vector<C2FieldDescriptor> _FIELD_LIST__unused; /**< structure fields */ 
    public: 
      typedef C2StoreIonUsageStruct _type; /**< type name shorthand */ 
      static const std::vector<C2FieldDescriptor> FieldList(); /**< structure fields factory */
} C2_PACK; 

const std::vector<C2FieldDescriptor> C2StoreIonUsageStruct::FieldList() { return _FIELD_LIST; } 

const std::vector<C2FieldDescriptor> C2StoreIonUsageStruct::_FIELD_LIST = {

将所有的C2FIELD展开变成:

    C2FieldDescriptor(&((_type*)(nullptr))->usage, "usage"),
    C2FieldDescriptor(&((_type*)(nullptr))->capacity, "capacity"),
    C2FieldDescriptor(&((_type*)(nullptr))->heapMask, "heap-mask"),
    C2FieldDescriptor(&((_type*)(nullptr))->allocFlags, "alloc-flags"),
    C2FieldDescriptor(&((_type*)(nullptr))->minAlignment, "min-alignment"),

将所有的内容拼接起来得到完整的结构体定义:

struct C2StoreIonUsageStruct {
    inline C2StoreIonUsageStruct() {
        memset(this, 0, sizeof(*this));
    }

    inline C2StoreIonUsageStruct(uint64_t usage_, uint32_t capacity_)
        : usage(usage_), capacity(capacity_), heapMask(0), allocFlags(0), minAlignment(0) { }

    uint64_t usage;        ///< C2MemoryUsage
    uint32_t capacity;     ///< capacity
    int32_t heapMask;      ///< ion heapMask
    int32_t allocFlags;    ///< ion allocation flags
    uint32_t minAlignment; ///< minimum alignment
    
    public: 
      enum : uint32_t { CORE_INDEX = kParamIndexStoreIonUsage }; 
    private: 
      const static std::vector<C2FieldDescriptor> _FIELD_LIST __unused; /**< structure fields */ 
    public: 
      typedef C2StoreIonUsageStruct _type; /**< type name shorthand */ 
      static const std::vector<C2FieldDescriptor> FieldList(); /**< structure fields factory */
} C2_PACK; 

const std::vector<C2FieldDescriptor> C2StoreIonUsageStruct::FieldList() { return _FIELD_LIST; } 

const std::vector<C2FieldDescriptor> C2StoreIonUsageStruct::_FIELD_LIST = {
    C2FieldDescriptor(&((_type*)(nullptr))->usage, "usage"),
    C2FieldDescriptor(&((_type*)(nullptr))->capacity, "capacity"),
    C2FieldDescriptor(&((_type*)(nullptr))->heapMask, "heap-mask"),
    C2FieldDescriptor(&((_type*)(nullptr))->allocFlags, "alloc-flags"),
    C2FieldDescriptor(&((_type*)(nullptr))->minAlignment, "min-alignment"),
};

好家伙,难道这就是宏魔法吗?!

DEFINE_AND_DESCRIBE_C2STRUCT定义在C2Param.h中,它的作用是给结构体定义一个匹配的CORE_INDEX,并且开始描述结构体的字段,该宏必须要在结构体定义的最后面使用。

从展开后的代码中我们可以看到,它定义了一个枚举常量CORE_INDEX,值为kParamIndexStoreIonUsage。
这里的CORE_INDEX就是上一篇文章中所说的BaseIndex,与结构体相绑定的独一无二的索引。所以在定义复杂结构体时除了结构体本身和对应的字符串外,还要定义一个索引值。索引的命名规则是以kParamIndex为前缀,加上结构体名称中的自定义部分。

索引值的定义参考C2Config.h中的C2ParamIndexKind,里面定义了框架使用的所有结构体索引。如果要自定义索引应该怎么办呢,索引值应该从什么地方开始?在C2Param.h中也有一个枚举,厂商自定义的索引从0x8000开始。

IS_VENDOR_FLAG  = 0x00008000,

除了CORE_INDEX外,DEFINE_AND_DESCRIBE_C2STRUCT还提供了描述结构体的方法FieldList,此方法会返回一个C2FieldDescriptor列表,构建C2FieldDescriptor对象需要传入字段相对结构体的偏移量,以及字段名称,具体C2FieldDescriptor是做什么用的,我们会在参数反射一文中做了解。

C2FIELD用于帮助生成C2FieldDescriptor的,它会自动帮助我们计算偏移量,有两点需要注意:

  • 填入的参数的顺序需要和结构体字段定义顺序相同;
  • 第二个宏参数填入的字段名称可以和结构体成员名称不同。

2、包含灵活数组的复杂结构体定义

3、No-Flex C2GlobalParam

4、Flex C2GlobalParam

5、C2PortParam

请添加图片描述

  • 11
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

青山渺渺

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值