结构 (RPC)

在封送所需的作方面,有几种类别的结构逐渐复杂。 它们从一个简单的结构开始,可以作为一个整体进行块复制,并继续执行必须按字段服务的复杂结构。

注意

与数组类别相比,很明显,只有高达 64k 大小的结构可以描述(该大小适用于结构的平面部分),而 SM 和 LG 数组没有等效项。

 

结构通用的成员

  • 对齐

    取消划分结构之前缓冲区的必要对齐方式。 有效值为 0、1、3 和 7(实际对齐减 1)。

  • memory_size

    内存中结构的大小(以字节为单位);对于符合性结构,此大小不包括数组的大小。

  • offset_to_array_description

    从当前格式字符串指针偏移到结构中包含的符合性数组的说明。

  • member_layout

    结构的每个元素的说明。 如果需要 endian 转换或类型是复杂结构,则 NDR 例程只需检查类型格式字符串的这一部分。

  • pointer_layout

    请参阅 指针布局 部分。

简单结构

简单结构仅包含基类型、固定数组和其他简单结构。 简单结构的主要功能是它可以作为一个整体进行块复制。

FC_STRUCT alignment<1> 
memory_size<2> 
member_layout<> 
FC_END

具有指针的简单结构

具有指针的简单结构仅包含基类型、指针、固定数组、简单结构和其他具有指针的简单结构。 由于布局<> 只有在执行尾数转换时才能访问,因此它放置在说明的末尾。

FC_PSTRUCT alignment<1> 
memory_size<2> 
pointer_layout<> 
member_layout<> 
FC_END

符合性结构

一个符合性结构仅包含基类型、固定数组和简单结构,并且必须包含一个符合性字符串或一个符合性数组。 此数组实际上可以包含在另一个一个一致性结构中,或者包含嵌入在此结构中的指针的符合性结构。

FC_CSTRUCT alignment<1> 
memory_size<2> 
offset_to_array_description<2> 
member_layout<> 
FC_END

具有指针的一致性结构

具有指针的一致结构仅包含基类型、指针、固定数组、简单结构和具有指针的简单结构;一个符合性结构必须包含一个符合性数组。 此数组实际上可以包含在另一个一个一致性结构中,或者包含嵌入在此结构中的指针的一致性结构。

FC_CPSTRUCT alignment<1> 
memory_size<2> 
offset_to_array_description<2> 
pointer_layout<> 
member_layout<> FC_END

符合性不同结构(带或不带指针)

一个符合性的不同结构仅包含简单类型、指针、固定数组、简单结构和具有指针的简单结构:一个符合性的不同结构必须包含一个符合性字符串或一个符合性变化的数组。 符合性字符串或数组实际上可以包含在另一个符合性结构中,或者包含嵌入在此结构中的指针的一致性结构。

FC_CVSTRUCT alignment<1> 
memory_size<2> 
offset_to_array_description<2> 
[pointer_layout<>] 
layout<> 
FC_END

硬结构

硬结构是一个旨在消除与处理复杂结构相关的陡峭惩罚的概念。 它派生自一个观察结果,即复杂结构通常只有一两个防止块复制的条件,因此与简单结构相比会破坏其性能。 罪犯通常是联合或枚举字段。

硬结构是具有枚举 16、内存中结束填充或作为最后一个成员的联合的结构。 这三个元素可防止结构进入以前的结构类别之一,这些类别具有较小的解释开销和最大的优化潜力,但不强制其进入成本高昂的复杂结构类别。

枚举 16 不得导致结构的内存和线路大小不同。 结构不能有任何符合性数组,也不能具有任何指针(除非属于联合的一部分):允许的唯一其他成员是基类型、固定数组和简单结构。

FC_HARD_STRUCTURE alignment<1> 
memory_size<2> 
reserved<4> 
enum_offset<2> 
copy_size<2> 
mem_copy_incr<2> 
union_description_offset<2>
member_layout<> 
FC_END

enum_offset<2> 字段提供内存中结构的开头到枚举 16(如果包含一个结构)的偏移量;否则,enum_offset<2> 字段为 –1。

copy_size<2> 字段提供结构中的字节总数,这些字节可能会被块复制到缓冲区/从缓冲区复制。 此总计不包括任何尾随联合,也不包括内存中的任何结束填充。 此值也是复制后缓冲区指针应递增的量。

mem_copy_incr<2> 字段是在处理任何尾随联合之前,内存指针应在块复制之后递增的字节数。 按此量递增(而不是copy_size<2 个> 字节)会生成指向任何尾随联合的正确内存指针。

复杂结构

复杂结构是包含一个或多个字段的结构,它们要么阻止结构被阻止复制,要么必须在封送或取消封送期间执行其他检查(例如,对枚举进行绑定检查)。 以下 NDR 类型属于此类别:

  • 简单类型:ENUM16、__INT3264(仅在 64 位平台上),是 [范围] 的整型
  • 结构末尾的对齐填充
  • 接口指针(它们使用嵌入式复杂体)
  • 忽略的指针(与 [忽略] 属性和FC_IGNORE标记相关)
  • 复杂数组、不同的数组、字符串数组
  • 具有至少一个非fixed 维度的多维一致性数组
  • 工会
  • 使用 [transmit_as]、 [represent_as]、 [wire_marshal]、 [user_marshal] 定义的元素
  • 嵌入式复杂结构
  • 结构末尾的填充

复杂结构具有以下格式说明:

FC_BOGUS_STRUCT alignment<1> 
memory_size<2> 
offset_to_conformant_array_description<2> 
offset_to_pointer_layout<2> 
member_layout<> 
FC_END 
[pointer_layout<>]

memory_size<2> 字段是内存中结构的大小(以字节为单位)。

如果结构包含一个符合性数组,则offset_to_conformant_array_description<2> 字段提供符合性数组说明的偏移量,否则为零。

如果结构具有指针,则offset_to_pointer_layout<2> 字段提供结构布局与指针布局的偏移量,否则此字段为零。

复杂结构pointer_layout<>字段的处理方式与其他结构略有不同。 复杂结构的pointer_layout<>字段仅包含结构本身中实际指针字段的说明。 复杂结构的pointer_layout<>字段中未描述任何嵌入数组、联合或结构中包含的任何指针。

注意

这与其他结构形成鲜明对比,这些结构也复制嵌入数组中包含的任何指针的说明,或者在其自己的指针_layout<>字段中的结构。

 

复杂结构的指针布局的格式也截然不同。 由于它仅包含实际指针成员的说明,并且由于复杂结构一次封送和取消封送一个字段,因此pointer_layout<>字段仅包含所有指针成员的指针说明。 没有开始FC_PP,也没有通常的pointer_layout<>信息。

结构成员布局说明

结构的布局说明包含以下一个或多个格式字符:

  • 任何基类型字符,如FC_CHAR等

  • 对齐指令。 有三个格式字符指定内存指针的对齐方式:FC_ALIGNM2、FC_ALIGNM4和FC_ALIGNM8。

    注意

    还有缓冲区对齐标记,FC_ALIGNB2到FC_ALIGNM8;不使用这些值。

     

  • 内存填充。 这些仅发生在结构说明的末尾,并表示在结构中符合性数组之前内存中填充的字节数:FC_STRUCTPADn,其中 n 是填充的字节数。

  • 任何嵌入的非基本类型(但请注意,一个符合性数组永远不会出现在结构布局中)。 这有一个 4 字节的说明:

    FC_EMBEDDED_COMPLEX memory_pad<1> 
    offset_to_description<2>,
    

    其中,偏移量不保证为 2 字节对齐。

    memory_pad<1> 是复杂字段之前内存中所需的填充。

    offset_to_description<2> 是嵌入类型的相对类型偏移量。

如果需要,在终止FC_END之前,可能还会有一个FC_PAD,以确保格式字符串在FC_END后的 2 字节边界对齐。