共用方式為


適用於更佳介面和方法設計的IDL技術

當您開發處理一致性和變體數據的 RPC 介面和方法時,請考慮使用下列 IDL 特定技術來改善安全性和效能。 本主題中參考的屬性是在處理一致性數據的方法參數上設定的IDL屬性(例如[size_is] 和 [max_is] 屬性)或變體數據(例如[length_is] 和 [字元串] 屬性)。

使用 [range] 屬性搭配一致性數據參數

[範圍] 屬性會指示 RPC 執行時間在資料取消分批處理期間執行額外的大小驗證。 具體來說,它會驗證傳遞為相關聯參數的數據所提供的大小是否在指定的範圍內。

[範圍] 屬性不會影響線格式。

如果線路上的值超出允許的範圍,RPC 會擲回RPC_X_INVALID_BOUND或RPC_X_BAD_STUB_DATA例外狀況。 這會提供額外的數據驗證層級,並有助於防止常見的安全性錯誤,例如緩衝區滿溢。 同樣地,使用 [範圍] 可以改善應用程式效能,因為標示為它的一致性數據具有明確的限制式可供 RPC 服務考慮。

RPC 伺服器存根記憶體管理規則

為已啟用 RPC 的應用程式建立 IDL 檔案時,請務必瞭解 RPC 伺服器存根記憶體管理規則。 應用程式可以使用 [範圍] 搭配上述的一致性數據,以及刻意避免套用可變長度數據 IDL 屬性,例如 [length_is] 一致數據,以改善伺服器資源使用率。

不建議將 [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])。 定義類似於傳遞至伺服器的數據 ([]]。

  • 針對 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