共用方式為


以回溯相容的方式變更介面

RPC 和 COM 版本控制理論中所述的方法可能因為許多原因而無法接受。 根據規則變更介面版本基本上需要新的用戶端不會與舊伺服器通訊。 這在現場部署的商務軟體經常不可能。 有時候,Windows 引進了介面變更,而沒有變更的 GUID 或版本。 這是需要與舊版伺服器通訊的新用戶端的結果,因為新用戶端支援舊和新介面的解決方案被視為不想要。

最佳做法

這些是無法變更介面 GUID 和版本時,解決線路不相容問題的合理方法。

  1. 讓應用程式知道另一端的功能。

    用戶端和伺服器具有通訊協定,可讓每個 (或至少新的用戶端) 建立夥伴的身分識別。 一般而言,讓新的用戶端知道舊伺服器和新伺服器所支援的功能。 當應用程式保留至線上內容時,可能會在執行任何 RPC 作業之前,透過用戶端執行的 XxxGetInfo 函式呼叫類型來支援此作業。 當應用程式以每部伺服器發行為基礎管理功能時,永遠不會發生與舊伺服器/用戶端不相容的呼叫,因為應用程式會控制哪個伺服器發出呼叫。 底線是應用程式主動防止發生不符的情況。 這可以與第二個做法一起執行。

  2. 引進新的遠端 API。

    如果在介面的結尾新增新的遠端方法,則不會與現有的方法衝突。 舊用戶端可以一律呼叫新的伺服器。 新的用戶端可以在不知道伺服器的身分識別的情況下呼叫新方法,前提是它會監看來自所呼叫伺服器的錯誤。 RPC 執行時間一律會在分派之前檢查每個介面的方法編號,以確保方法位於適當的 v 資料表內。 對於伺服器未知的方法,RPC 執行時間會引發例外狀況RPC_S_PROCNUM_OUT_OF_RANGE。 此例外狀況只會在此特定情況下引發。 因此,新的用戶端可以針對例外狀況watch,以表示呼叫已進入舊伺服器,並可正常修改其行為。

  3. 只在新的方法中引進新的參數或新的資料類型。

    引進新方法的其中一個原因是避免資料不相容。 如果引進或修改新的資料類型,則主要應該只在新的方法中使用 (或方法) 。 如需不相容資料類型變更的範例,請參閱不相容 變更 的範例。 此規則唯一值得注意的例外狀況會在專案四中說明。

  4. 透過包裝函式對應新的參數或新的資料類型。

    當新的參數或資料類型必須公開給使用者,但實際上不需要個別遠端,或可以對應到舊的資料類型或參數時,這個解決方案就會套用。 例如,許多系統 API 會輪轉並執行遠端呼叫。 他們可能或可能不會執行某種從使用者已知資料類型到基礎 RPC 呼叫中實際使用的資料類型的對應。 因此,請務必檢查使用者介面中的變更是否需要傳播為遠端介面的變更。

    使用者直接呼叫遠端 API 時,可能會發生類似的情況,但可能會引進包裝函式來執行新的類型對應,或需要執行一些其他動作。 介面定義語言 (IDL) 有數種方式可協助重新對應,也就是 [call_as]、[transmit_as] 和 [wire_marshal]。 [call_as] 屬性會在用戶端和伺服器上引進函式包裝函式。 這兩者都會放在使用者程式碼與封送處理器之間。 其他屬性會處理直接類型對應。 對於擴充問題,[call_as] 是最常使用的,而且最容易瞭解及操作,而不會發生錯誤。

  5. 透過無預設值等位修改資料類型。

    變更屬性或資料類型通常會導致線路不相容。 如需範例 ,請參閱不相容變更的 範例。 不過,在沒有預設子句的聯集案例中,可能會以類似超出範圍之程式的案例來管理不相容,如先前所述。 此配置很容易適用于使用等位的熱門 XxxINFO 類型。

    例如,呼叫如下

    XxxGetInfo( [in] level, [out] XxxINFO  * pInfo );
    

    可以在層級 1、2 或 3 上傳回信息,其中 XxxINFO 是三個分支的聯集:1、2 和 3。

  6. 使用 [range] 屬性來指定範圍。

    您可以在簡單的縮放類型上指定 [range] 屬性,而不中斷回溯相容性。 此屬性不會影響連線格式,但在取消封存 RPC 期間,會檢查連線上的值,以確認其位於 .idl 檔案中指定的範圍內。 如果沒有,則會擲回RPC_X_INVALID_BOUND例外狀況。 如果伺服器知道大小上限的陣列,這特別有用。

    例如:

    HRESULT Method1( [in, range(0,100)] ULONG m, [size_is(m)] ULONG *plong); 
    

當指定的層級為 4 且 arm 遺失時,RPC 行為取決於等位的定義。 針對已定義預設子句的聯集,RPC 會針對與已知 arm (標籤不同的類型傳送預設子句中所指出的類型,在此案例中為 1、2 或 3 以外的任何專案) 。 若為無預設聯集,unmarshaler 會引發例外狀況,因為根據定義,沒有預設會回復。 例外狀況RPC_S_INVALID_TAG。

同樣地,新的用戶端可以在發現它稱為舊伺服器時調整其行為。

遵循這些建議的做法是,如果必須設計可在未來擴充的可遠端資料類型,請在 IDL 檔案中使用無預設值聯集。 假設有選擇,封裝的等位會稍微更簡潔。

由於 NDR64 線路通訊協定的內部標記法,本節稍早所提供新增手部的建議必須符合下列條件:新增的新 arm 無法變更等位的對齊方式,特別是,最大對齊方式不應變更。 這通常不是問題,因為 arm 中的指標會強制對齊 8。 每個 arm 都是 arm 類型的指標的設計,是滿足需求的一種全新方式。