参数描述符
如前所述,存在 –Oi 和 –Oif 样式参数描述符。
–Oi 参数描述符
完全解释的存根需要 RPC 调用中每个参数的其他信息。 过程的参数说明紧跟在过程说明之后。
参数描述符
[] 中 [] 或返回简单类型参数的格式为:
FC_IN_PARAM_BASETYPE
simple_type<1>
–或–
FC_RETURN_PARAM_BASETYPE
simple_type<1>
其中simple_type<1> 是指示简单类型的 FC 标记。 代码如下所示:
4e FC_IN_PARAM_BASETYPE
53 FC_RETURN_PARAM_BASETYPE
其他 –Oi
参数描述符
所有其他参数类型的说明的格式为:
param_direction<1>
stack_size<1>
type_offset<2>
其中每个说明的param_direction<1> 字段必须是下表所示的字段之一。
十六进制 | 旗 | 意义 |
---|---|---|
4d | FC_IN_PARAM | 参数中的一个。 |
50 | FC_IN_OUT_PARAM | in/out 参数。 |
51 | FC_OUT_PARAM | out 参数。 |
52 | FC_RETURN_PARAM | 过程返回值。 |
4f | FC_IN_PARAM_NO_FREE_INST | 以 xmit/rep 作为无释放的参数。 |
stack_size<1> 是堆栈上参数的大小,以参数在堆栈上占用的整数数表示。
注意
64 位平台上不支持 –Oi 模式。
type_offset<2> 字段是类型格式字符串表中的偏移量,指示参数的类型描述符。
–Oif 参数描述符
参数说明有两种可能的格式,一种用于基类型,另一种用于所有其他类型。
基类型:
PARAM_ATTRIBUTES<2>
stack_offset<2>
type_format_char<1>
unused<1>
其他:
PARAM_ATTRIBUTES<2>
stack_offset<2>
type_offset<2>
在这两个stack_offset<2> 都指示虚拟参数堆栈上的偏移量(以字节为单位)。 对于基类型,参数类型由与类型对应的格式字符直接提供。 对于其他类型的,type_offset<2> 字段在参数的类型描述符所在的类型格式字符串表中提供偏移量。
参数属性字段的定义如下:
typedef struct
{
unsigned short MustSize : 1; // 0x0001
unsigned short MustFree : 1; // 0x0002
unsigned short IsPipe : 1; // 0x0004
unsigned short IsIn : 1; // 0x0008
unsigned short IsOut : 1; // 0x0010
unsigned short IsReturn : 1; // 0x0020
unsigned short IsBasetype : 1; // 0x0040
unsigned short IsByValue : 1; // 0x0080
unsigned short IsSimpleRef : 1; // 0x0100
unsigned short IsDontCallFreeInst : 1; // 0x0200
unsigned short SaveForAsyncFinish : 1; // 0x0400
unsigned short Unused : 2;
unsigned short ServerAllocSize : 3; // 0xe000
} PARAM_ATTRIBUTES, *PPARAM_ATTRIBUTES;
- 仅当参数必须调整大小时,才会设置 MustSize 位。
- 如果服务器必须调用参数的 NdrFree* 例程,则设置 MustFree 位。
- IsSimpleRef 位设置为指向其他任何指针的引用指针的参数,并且没有分配属性。 对于此类类型,参数说明的type_offset<>字段(基类型的引用指针除外)提供引用类型的偏移量;直接跳过引用指针。
- IsDontCallFreeInst 位是为不应调用其免费实例例程的某些represent_as参数设置的。
- 如果参数为 [out],则 ServerAllocSize 位为非零位,如果参数为 [out],则为 [in,out] 指针,或指向枚举的指针,并将在服务器解释器的堆栈上初始化,而不是使用调用 I_RpcAllocate。 如果为非零,则此值乘以 8 以获取参数的字节数。 请注意,这样做意味着始终为指针分配至少 8 个字节。
- IsBasetype 位设置为由主 –Oif 解释器循环封送的简单类型。 具体而言,具有范围属性的简单类型不会标记为基类型,以便使用 FC_RANGE 令牌强制范围例程封送处理。
- IsByValue 位是为按值发送的复合类型设置的,但对于简单类型未设置,无论参数是否为指针。 其设置的复合类型是结构、联合、transmit_as、represent_as、wire_marshal 和 SAFEARRAY。 通常,为了在 –Oicf 解释器中引入主解释器循环的好处,以确保正确取消引用非简单参数(称为复合类型参数)。 此位从未在早期版本的解释器中使用。