结构 (RPC)

结构分为几种类别,根据它们在封送处理时需要执行的操作的复杂度,它们按照从低到高的顺序排列。 首先是可以作为一个整体进行块复制的简单结构,然后是必须逐个字段服务的复杂结构。

注意

与数组类别相比,很明显,只能描述最大大小为 64k 的结构(此大小适用于结构的平面部分),也就是说,SM 和 LG 数组没有任何等效项。

 

结构共有的成员

  • alignment

    在拆收结构之前对缓冲区进行的必要对齐。 有效值为 0、1、3 和 7(实际对齐减 1)。

  • memory_size

    内存中的结构的大小(以字节为单位);对于一致结构,此大小不包含数组的大小。

  • offset_to_array_description

    当前格式字符串指针与结构中包含的一致数组的说明之间的偏移量。

  • member_layout

    结构的每个元素的说明。 如果需要执行字节排序方式转换或者类型是复杂结构,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

硬结构

硬结构是一个概念,旨在消除处理复杂结构时涉及的严厉处罚。 它源自于这样一个观察:复杂结构通常只有一两个阻止块复制的条件,因此与简单结构相比,它的性能会受到影响。 罪魁祸首通常是联合或枚举字段。

硬结构是一种将 enum16、内存中的结尾填充或联合用作最后一个成员的结构。 这三种元素会导致结构无法归入前面的结构类别(这些类别具有较小的解释开销和最大的优化潜力)之一,但不会强制将结构归入代价高昂的复杂结构类别。

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

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> 字段如果包含 1,将提供内存中的结构的开头与 enum16 之间的偏移量;否则 enum_offset<2> 字段将为 -1。

copy_size<2> 字段将提供结构中的字节总数,可以将结构块复制到缓冲区中或者从缓冲区中块复制结构。 此总数不包含任何尾随联合或内存中的任何结尾填充。 此值也是缓冲区指针在复制之后应当递增的量。

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

复杂结构

复杂结构是指包含一个或多个字段的任何结构,这些字段要么导致无法对结构进行块复制,要么在封送处理或拆收处理期间必须对其执行其他检查(例如对枚举执行绑定检查)。 以下 NDR 类型属于这一类别:

  • 简单类型:ENUM16、__INT3264(仅限 64 位平台)、具有 [range] 的整型
  • 结构末尾的对齐填充
  • 接口指针(它们使用嵌入式复合体移动)
  • 忽略的指针(与 [ignore] 属性和 FC_IGNORE 令牌相关)
  • 复杂数组、可变数组、字符串数组
  • 具有至少一个非固定维度的多维一致数组
  • 联合
  • 使用 [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<> 字段中未说明任何嵌入式数组、联合或结构内包含的任何指针。

注意

这种结构与其他结构相反,其他结构还会将嵌入式数组或结构中包含的任何指针的说明复制到它们自己的 pointer_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 字节边界处对齐。