使用英语阅读

通过


句柄数

过程地址句柄的格式字符串说明中多达两个部分。 第一部分是过程说明handle_type<1> 字段,用于指示隐式句柄。 此部分始终存在。 第二部分是过程中任何显式句柄的参数说明。 以下各节将介绍这两者,并讨论了绑定句柄问题的存根描述符结构的其他 MIDL 编译器支持。

隐式句柄

如果过程使用隐式句柄进行绑定,则过程说明的 handle_type<1> 字段包含三个有效的非零值之一。 在存根描述符结构的 IMPLICIT_HANDLE_INFO 字段中找到对隐式句柄的 MIDL 编译器支持:

typedef  (__RPC_FAR * GENERIC_BINDING_ROUTINE)();

typedef struct 
  {
  GENERIC_BINDING_ROUTINE  pfnBind;
  GENERIC_BINDING_ROUTINE  pfnUnbind;
  } GENERIC_BINDING_ROUTINE_PAIR;
  
typedef struct __GENERIC_BINDING_INFO 
  {
  void __RPC_FAR*          pObj;
  unsigned char            Size;
  GENERIC_BINDING_ROUTINE  pfnBind;
  GENERIC_BINDING_ROUTINE    pfnUnbind;
  } GENERIC_BINDING_INFO,  *PGENERIC_BINDING_INFO;

union 
  {
  handle_t*                pAutoHandle;
  handle_t*                pPrimitiveHandle;
  PGENERIC_BINDING_INFO    pGenericBindingInfo;
  } IMPLICIT_HANDLE_INFO;

如果过程使用自动句柄, 则 pAutoHandle 成员包含存根定义的自动句柄变量的地址。

如果过程使用隐式基元句柄, 则 pPrimitiveHandle 成员包含存根定义基元句柄变量的地址。

最后,如果过程使用隐式泛型句柄, 则 pGenericBindingInfo 成员保留指向相应 GENERIC_BINDING_INFO 结构的指针的地址。 数据结构MIDL_STUB_DESC包含指向GENERIC_BINDING_PAIR结构集合的指针。 此集合零位置的条目是为与 pGenericBindingInfoIMPLICIT_HANDLE_INFO 中引用的泛型绑定句柄对应的绑定取消绑定例程保留的。 隐式绑定句柄的类型在格式字符串中指示。

显式句柄

有三种可能的显式句柄类型:上下文、泛型和基元。 如果显式句柄 (或仅 [out] 上下文句柄(其处理方式与) 相同),则绑定句柄信息显示为过程参数之一。 三种可能的说明如下所示。

基元

FC_BIND_PRIMITIVE, flag<1>, offset<2>.

标志<1> 指示句柄是否由指针传递。

偏移量<2> 提供从堆栈开头到基元句柄的偏移量。

备注

类型格式字符串中的基元句柄说明将简化为单个FC_IGNORE。

 

泛型

FC_BIND_GENERIC, flag_and_size<1>, offset<2>, binding_routine_pair_index<1>, FC_PAD

flag_and _size<1> 具有上旗小号和小号小号。 标志指示句柄是否由指针传递。 size 字段提供用户定义的泛型句柄类型的大小。 此大小在 32 位系统上限制为 1、2 或 4 个字节,在 64 位系统上限制为 1、2、4 或 8 个字节。

offset<2> 字段提供从指针堆栈开始到给定大小的数据的偏移量。

binding_routine_pair_index<1> 字段将存根描述符的 aGenericBindingRoutinePairs 字段的索引提供给泛型句柄的 绑定取消绑定 例程函数指针。

备注

类型格式的泛型句柄说明只是相关数据类型的说明。

 

上下文

FC_BIND_CONTEXT flags<1> offset<2> context_rundown_routine_index<1> param_num<1>

标志<1> 指示句柄的传递方式及其类型。 下表显示了有效标志。

Hex 标志
80 HANDLE_PARAM_IS_VIA_PTR
40 HANDLE_PARAM_IS_IN
20 HANDLE_PARAM_IS_OUT
21 HANDLE_PARAM_IS_RETURN
08 NDR_STRICT_CONTEXT_HANDLE
04 NDR_CONTEXT_HANDLE_NO_SERIALIZE
02 NDR_CONTEXT_HANDLE_SERIALIZE
01 NDR_CONTEXT_HANDLE_CANNOT_BE_NULL

 

前四个标志一直存在,最后四个标志是在 Windows 2000 中添加的。

offset<2> 字段提供从堆栈开始到上下文句柄的偏移量。

context_rundown_routine_index<1 为用于此上下文句柄的 rundown 例程提供 Stub 描述符的 apfnNdrRundownRoutines 字段的>索引。 编译器始终生成索引。 对于没有运行例程的例程,这是一个索引,指向保留 null 的表位置。

对于 –Oi2 中内置的存根,param_num<1> 提供从零开始的序号计数,指定它在给定过程中的上下文句柄。

对于解释器的早期版本,param_num<1> 在其过程中提供上下文句柄的参数编号(从零开始)。

备注

类型格式字符串中的上下文句柄说明在说明中没有偏移量<2> 。

 

New –Oif 标头

如前所述, –Oif 标头在 –Oi 标头上展开。 为方便起见,所有字段都如下所示:

(旧标头)

handle_type<1> 
Oi_flags<1>
[rpc_flags<4>]
proc_num<2>  
stack_size<2>
[explicit_handle_description<>]

(–Oif 扩展)

constant_client_buffer_size<2>
constant_server_buffer_size<2>
INTERPRETER_OPT_FLAGS<1>
number_of_params<1>

constant_client_buffer_size<2> 提供可能由编译器预先计算的封送缓冲区的大小。 这可能只是部分大小,因为 ClientMustSize 标志会触发大小调整。

constant_server_buffer_size<2> 提供由编译器预计算的封送缓冲区的大小。 这可能只是部分大小,因为 ServerMustSize 标志会触发大小调整。

INTERPRETER_OPT_FLAGS在 Ndrtypes.h 中定义:

typedef struct
  {
  unsigned char   ServerMustSize      : 1;    // 0x01
  unsigned char   ClientMustSize      : 1;    // 0x02
  unsigned char   HasReturn           : 1;    // 0x04
  unsigned char   HasPipes            : 1;    // 0x08
  unsigned char   Unused              : 1;
  unsigned char   HasAsyncUuid        : 1;    // 0x20
  unsigned char   HasExtensions       : 1;    // 0x40
  unsigned char   HasAsyncHandle      : 1;    // 0x80
  } INTERPRETER_OPT_FLAGS, *PINTERPRETER_OPT_FLAGS;
  • 如果服务器需要执行缓冲区大小调整传递,则会设置 ServerMustSize 位。
  • 如果客户端需要执行缓冲区大小调整传递,则会设置 ClientMustSize 位。
  • 如果过程具有返回值,则设置 HasReturn 位。
  • 如果需要使用管道包来支持管道参数,则设置 HasPipes 位。
  • 如果过程是异步 DCOM 过程,则设置 HasAsyncUuid 位。
  • HasExtensions 位指示使用 Windows 2000 及更高版本的扩展。
  • HasAsyncHandle 位指示异步 RPC 过程。

HasAsyncHandle 位最初已用于异步支持的不同 DCOM 实现,因此不能用于 DCOM 中的当前样式异步支持。 HasAsyncUuid 位当前指示这一点。