方向屬性
每一個方法參數都可以與 InAttribute 屬性、OutAttribute 屬性或兩者的設定產生關聯。 您可以在設計階段套用方向屬性,修改 Managed 和 Unmanaged 記憶體之間的 Run-Time 封送處理。
InAttribute 和 OutAttribute 是位於 System.Runtime.InteropServices 命名空間中,而且相當於介面定義語言 (IDL) 的介面屬性 [in]、[out]、[in/out] 和 [out, retval]。
注意事項 |
---|
Managed 方法簽章 (Signature) 的傳回值永遠會對應至型別程式庫中的 [out, retval]。沒有您可以套用的對等方向屬性。 |
方向屬性是選擇性的。 當您想要更改封送處理器的預設行為時,可以將方向屬性套用至方法參數中。 如果省略方法參數中的方向屬性,封送處理器會根據參數的型別 (數值或參考) 和其修飾詞 (Modifier) (如果有的話),決定方向性流動。
某些語言提供關鍵字,可以讓您修改方法參數的方向性流動。 下表列出 Visual Basic 2005 和 C# 所提供與方向相關的關鍵字,並顯示對等的 IDL 介面屬性。
Visual Basic 2005 |
C# |
IDL 屬性 |
---|---|---|
ByVal |
沒有對等用法。 |
[in] |
ByRef |
ref |
[in/out] |
沒有對等用法。 |
out |
[out] |
ByRef、ref 和 out 參數修飾詞 (Modifier) 會使得方法引數以傳址 (By Reference) 方式進行封送處理,而非使用傳值 (By Value) 方式。 以傳值方式傳遞的方法引數會封送處理至 Unmanaged 程式碼做為堆疊上的值;而以傳址方式傳遞的引數會封送處理為堆疊上的指標。 下圖顯示具有參數修飾詞的實值型別 (Value Type) 和參考型別 (Reference Type) 之預設的封送處理行為。
Unmanaged 程式碼的方法引數之預設封送處理
由於效能因素,以傳值方式傳遞的參考型別 (類別、陣列、字串和介面) 會預設封送處理為 In 參數。 除非您將 InAttribute 和 OutAttribute (或 OutAttribute) 套用至方法參數,否則不會看到這些型別的變更。 StringBuilder 類別,是這個規則的例外,會封送處理為 In/Out 參數。
關於方向屬性,Interop 封送處理器將保證以下行為:
Interop 封送處理器並不會產生從 Unmanaged 程式碼傳遞而來的 In 參數的寫入作業。 因此,Unmanaged 程式碼可以安全地將指標傳遞給唯讀頁面,或將指標傳遞給目前存取的資料。
當複製的物件包含配置的物件 (例如 BSTR) 時,封送處理器永遠會執行正確的配置順序和 In/Out 設定所需要的解構。
精確無誤地在您的程式碼中套用方向屬性是非常重要的。 在 Managed 程式碼中正確地將 InAttribute 和 OutAttribute 套用至參數,可確保型別程式庫匯出工具 (Tlbexp.exe) 在對應的型別程式庫中使用這些位元來設定 In/Out 位元;這對可以 Pin (如某些陣列和類別) 的參考型別特別重要。