分享方式:


自訂參數封送處理

當 .NET 執行階段的預設參數封送處理行為不能滿足您的要求時,可以使用 System.Runtime.InteropServices.MarshalAsAttribute 屬性來自訂參數的封送處理方式。 停用執行階段封送處理時,不會套用這些自訂功能。

注意

P/InvokesCOM 的來源產生的 Interop 只會遵守參數上 MarshalAsAttribute 子集的一小部分。 建議將 MarshalUsingAttribute 改為用於來源產生的 Interop。 如需詳細資訊,請參閱 來源產生的自訂封送處理

自訂字串參數

.NET 有各種不同的格式可用於封送處理字串。 這些方法分為 C 樣式字串和以 Windows 為中心的字串格式的不同區段。

C 樣式字串

每種格式都將傳遞以 Null 結尾的字串至機器碼。 它們因原生字串的編碼方式而不同。

System.Runtime.InteropServices.UnmanagedType 編碼方式
LPStr ANSI
LPUTF8Str UTF-8
LPWStr UTF-16
LPTStr UTF-16

UnmanagedType.VBByRefStr 格式會稍有不同。 與 LPWStr 一樣,它將字串封送處理成以 UTF-16 編碼的原生 C 樣式字串。 不過,受控簽章允許您傳參考方式傳入字串,而符合的原生簽章接受以傳值方式傳入的字串。 此區別可讓您使用原生 API,該 API 接受以傳值方式傳入的字串,並在不必使用 StringBuilder 的情況下就地修改它。 我們建議您不要以手動方式使用此格式,因為它很容易導致與不相符的原生和受控簽章混淆。

以 Windows 為中心的字串格式

當與 COM 或 OLE 介面互動時,您可能會發現原生函式接受以 BSTR 引數形式表示的字串。 您可以使用 UnmanagedType.BStr 非受控型別將字串封送處理為 BSTR

如果您正在與 WinRT API 進行互動,則可以使用 UnmanagedType.HString 格式將字串封送處理為 HSTRING

自訂陣列參數

.NET 也提供您多種方法來封送處理陣列參數。 如果您正在呼叫接受 C 樣式陣列的 API,請使用 UnmanagedType.LPArray 非受控型別。 如果陣列中的值需要自訂封送處理,則您可以使用 [MarshalAs] 屬性上的 ArraySubType 欄位來進行此動作。

如果您使用 COM API,則可能需要將陣列參數封送處理為 SAFEARRAY*。 若要這樣做,您可以使用 UnmanagedType.SafeArray 非受控型別。 在自訂 object 欄位表格中可以看到 SAFEARRAY 元素的預設型別。 您可以使用 MarshalAsAttribute.SafeArraySubTypeMarshalAsAttribute.SafeArrayUserDefinedSubType 欄位來自訂 SAFEARRAY 的確切元素型別。

自訂布林值或十進位參數

如需封送處理布林值或十進位參數的相關資訊,請參閱自訂結構封送處理

自訂物件參數 (僅限 Windows)

在 Windows 上,.NET 執行階段提供不同的方式來將物件參數封送處理為機器碼。

封送處理為特定的 COM 介面

如果您的 API 接受 COM 物件的指標,則可以在 object 型別參數上使用下列任一 UnmanagedType 格式,以告知 .NET 封送處理為這些特定介面:

  • IUnknown
  • IDispatch
  • IInspectable

此外,如果您的型別標示為 [ComVisible(true)] 或您正在封送處理 object 型別,則可以使用 UnmanagedType.Interface 格式將物件封送處理為型別之 COM 檢視的 COM 可呼叫包裝函式。

封送處理為 VARIANT

如果您的原生 API 接受 Win32 VARIANT,則可以使用 object 參數上的 UnmanagedType.Struct 格式將物件封送處理為 VARIANT。 有關 .NET 型別和 VARIANT 型別之間的對應,請參閱有關自訂 object 欄位的文件。

自訂封送處理器

如果要將原生 COM 介面投射到其他受控型別,可以使用 UnmanagedType.CustomMarshaler 格式和 ICustomMarshaler 的實作來提供自己的自訂封送處理程式碼。