適用于更佳介面和方法設計的 IDL 技術
當您開發處理一致性和變體資料的 RPC 介面和方法時,請考慮使用下列 IDL 特定技術來改善安全性和效能。 本主題所參考的屬性是在處理一致性資料的方法參數上設定的 IDL 屬性(例如,[size_is] 和 [max_is] 屬性)或變體資料(例如[ length_is ] 和 [ string ] 屬性)。
使用 [range] 屬性搭配一致性資料參數
[ range ] 屬性會指示 RPC 執行時間在資料取消分清過程中執行其他大小驗證。 具體來說,它會驗證傳遞為相關聯參數的資料所提供的大小是否在指定的範圍內。
[ range ] 屬性不會影響連線格式。
如果線路上的值超出允許的範圍,RPC 會擲回RPC_X_INVALID_BOUND或RPC_X_BAD_STUB_DATA例外狀況。 這會提供額外的資料驗證層級,並有助於防止常見的安全性錯誤,例如緩衝區滿溢。 同樣地,使用 [ range ] 可以改善應用程式效能,因為標示它的一致性資料已明確定義條件約束可供 RPC 服務考慮。
RPC 伺服器存根記憶體管理規則
為已啟用 RPC 的應用程式建立 IDL 檔案時,請務必瞭解 RPC 伺服器存根記憶體管理規則。 應用程式可以使用 [ range ] 搭配上述的一致性資料來改善伺服器資源使用率,並刻意避免使用 [ length_is ] 等可變長度資料 IDL 屬性的應用程式來符合資料。
不建議將 [ length_is ] 應用程式到 IDL 檔案中定義的資料結構欄位。
可變長度資料參數的最佳做法
以下是定義變數大小資料結構、方法參數和欄位的 IDL 屬性時要考慮的幾個最佳做法。
使用早期相互關聯。 通常最好定義變數大小參數或欄位,使其會在控制整數類型之後立即發生。
例如,
earlyCorr ( [in, range(MIN_COUNT, MAX_COUNT)] long size, [in,size_is(size)] char *pv );
勝過
lateCorr ( [in,size_is(size)] char *pv, [in, range(MIN_COUNT, MAX_COUNT)] long size) );
其中, earlyCorr 會在可變長度資料參數之前立即宣告 size 參數,而 lateCorr 會在它之後宣告 size 參數。 使用早期對應可改善整體效能,特別是在經常呼叫 方法的情況下。
對於標示為 [ out, size_is ] 屬性元組的參數,以及用戶端上已知資料長度或用戶端具有合理上限的參數,方法定義應類似下列參數屬性和順序:
outKnownSize ( [in,range(MIN_COUNT, MAX_COUNT)] long lSize, [out,size_is(lSize)] UserDataType * pArr );
在此情況下,用戶端會為 pArr 提供固定大小緩衝區 ,讓伺服器端 RPC 服務以良好的保證配置合理大小的緩衝區。 請注意,在範例中,資料會從伺服器 ([ out ]) 接收。 定義類似于傳遞至伺服器的資料([ in ])。
針對 RPC 應用程式的伺服器端元件決定資料長度的情況,方法定義應該類似下列內容:
typedef [range(MIN_COUNT,MAX_COUNT)] long RANGED_LONG; outUnknownSize ( [out] RANGED_LONG *pSize, [out,size_is(,*pSize)] UserDataType **ppArr );
RANGED_LONG 是針對用戶端和伺服器存根所定義的型別,以及用戶端可以正確預期的指定大小。 在此範例中,用戶端會將 ppArr 傳遞 為 Null ,而 RPC 伺服器應用程式元件會配置正確的記憶體數量。 傳回時,用戶端上的 RPC 服務會為傳回的資料配置記憶體。
如果用戶端想要將大型一致性陣列的子集傳送至伺服器,應用程式可以指定子集的大小,如下列範例所示:
inConformantVaryingArray ( [in,range(MIN_COUNT,MAX_COUNT)] long lSize, [in] long lLength, [in,size_is(lSize), length_is(lLength)] UserDataType *pArr );
如此一來,RPC 只會在網路上傳輸 陣列的 lLength 元素。 不過,此定義會強制 RPC 服務在伺服器端配置大小 為 lSize 的記憶體。
如果用戶端應用程式元件決定伺服器可以傳回的陣列大小上限,但允許伺服器傳輸該陣列的子集,則應用程式可以藉由定義類似下列範例的 IDL 來指定這類行為:
inMaxSizeOutLength ( [in, range(MIN_COUNT, MAX_COUNT)] long lSize, [out] long *pLength, [out,size_is(lSize), length_is(*pLength)] UserDataType *pArr );
用戶端應用程式元件會指定陣列的大小上限,而伺服器會指定它傳回給用戶端的元素數目。
如果伺服器應用程式元件需要將字串傳回給用戶端應用程式元件,而且用戶端知道要從伺服器傳回的大小上限,應用程式可以使用一致字串類型,如下列範例所示:
outStringKnownSize ( [in,range(MIN_COUNT, MAX_STRING)] long lSize, [out,size_is(lSize),string] wchar_t *pString );
如果用戶端應用程式元件不應該控制字元串的大小,RPC 服務可以特別配置記憶體,如下列範例所示:
outStringUnknownSize ( [out] LPWSTR *ppStr );
呼叫 RPC 方法時,用戶端應用程式元件必須在 上將 ppStr 設定 為 Null 。