處理
程式位址控制碼的格式字串描述中,有兩個部分。 第一個部分是程式描述的 < 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_INFO中pGenericBindingInfo所參考的泛型系結控制碼。 隱含系結控制碼的類型是以格式字串表示。
有三種可能的明確控制碼類型:內容、泛型和基本類型。 如果明確控制碼 (或 [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 標頭會展開 –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 位目前表示此情況。