閱讀英文

共用方式為


處理

程式位址控制碼的格式字串描述中,有兩個部分。 第一個部分是程式描述的 < handle_type 1 > 個欄位,用來表示隱含控制碼。 這個部分一律存在。 第二個部分是程式中任何明確控制碼的參數描述。 下列各節將說明這兩者,以及系結控制碼問題之 Stub 描述元結構的其他 MIDL 編譯器支援討論。

隱含控制碼

如果程式使用隱含控制碼進行系結,則程式描述的 handle_type < 1 > 欄位包含三個有效非零值的其中一個。 在 Stub 描述元結構的 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 結構的集合指標。 此集合之零位置的專案會保留給系取消系結常式,其對應至IMPLICIT_HANDLE_INFOpGenericBindingInfo所參考的泛型系結控制碼。 隱含系結控制碼的類型是以格式字串表示。

明確控制碼

有三種可能的明確控制碼類型:內容、泛型和基本類型。 如果明確控制碼 (或 [out] 唯一的內容控制碼,其處理方式與) 相同,系結控制碼資訊會顯示為程式的其中一個參數。 這三個可能的描述如下。

Primitive

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 > 具有上層旗標可擷取和大小較低的 nibble。 旗標會指出控制碼是否由指標傳遞。 size 欄位提供使用者定義-泛型控制碼類型的大小。 此大小限制為 32 位系統上的 1、2 或 4 個位元組,而 64 位系統上有 1、2、4 或 8 個位元組。

offset < 2 > 欄位會提供指標堆疊開頭的位移,以及指定大小的資料。

binding_routine_pair_index < 1 > 欄位會將索引提供給 Stub 描述元的 aGenericBindingRoutinePairs 欄位,以 系結解除系結 一般控制碼的常式函式指標。

注意

類型格式的泛型控制碼描述只是相關資料類型的描述。

 

Context

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 會將索引提供給用於此內容控制碼之 Stub 描述項的apfnNdrRundownRoutines> 欄位。 編譯器一律會產生索引。 對於沒有取消常式的常式,這是保存 Null 之資料表位置的索引。

針對 內建 –Oi2的存根,param_num < 1 > 提供序數計數,從零開始,指定它位於指定程式中的內容控制碼。

對於舊版解譯器,param_num < 1 > 會在其程式中提供內容控制碼的參數編號,從零開始。

注意

類型格式字串中的內容控制碼描述不會有描述中的位移 < 2 > 。

 

新的 –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 位目前表示此情況。