自定义参数封送 Customizing parameter marshalling

本文内容

当 .NET 运行时的默认参数封送行为不满足要求时,可以使用 System.Runtime.InteropServices.MarshalAsAttribute 属性自定义参数的封送方式。

自定义字符串参数Customizing string parameters

.NET 具有各种格式可用来封送字符串。这些方法分为有关 C 样式字符串和以 Windows 为中心的字符串的不同格式部分。

C 样式字符串C-Style strings

其中每个格式都会将以 null 结尾的字符串传递到本机代码。它们的差别在于本机字符串的编码。

System.Runtime.InteropServices.UnmanagedType编码
LPStrANSI
LPUTF8StrUTF-8
LPWStrUTF-16

UnmanagedType.VBByRefStr 格式稍有不同。LPWStr 一样,该格式会将字符串封送到采用 UTF-16 编码的本机 C 样式字符串。但是,托管签名允许你按引用传入字符串,而匹配的本机签名会按值获取字符串。这一区别允许你使用按值获取字符串的本机 API,并对其进行就地修改而无需使用 StringBuilder我们建议不要手动使用此格式,因为很容易导致与不匹配的本机和托管签名混淆。

以 Windows 为中心的字符串格式Windows-centric string formats

与 COM 或 OLE 接口交互时,可能会发现本机函数将字符串用作 BSTR 参数。可以使用 UnmanagedType.BStr 非托管类型将字符串作为 BSTR 进行封送。

如果要与 WinRT API 交互,则可以使用 UnmanagedType.HString 格式将字符串作为 HSTRING 进行封送。

自定义数组参数Customizing array parameters

.NET 还提供多种方式来封送数组参数。如果要调用获取 C 样式数组的 API,则使用 UnmanagedType.LPArray 非托管类型。如果数组中的值需要进行自定义封送,则可以为其使用 [MarshalAs] 属性上的 ArraySubType 字段。

如果使用的是 COM API,则可能必须将数组参数作为 SAFEARRAY* 进行封送。为此,可以使用 UnmanagedType.SafeArray 非托管类型。自定义 object 字段上的表中显示了 SAFEARRAY 的元素的默认类型。可以使用 MarshalAsAttribute.SafeArraySubTypeMarshalAsAttribute.SafeArrayUserDefinedSubType 字段自定义 SAFEARRAY 的确切元素类型。

自定义布尔或十进制参数Customizing boolean or decimal parameters

有关封送布尔或十进制参数的信息,请参阅自定义结构封送

自定义对象参数(仅适用于 Windows)Customizing object parameters (Windows-only)

在 Windows 上,.NET 运行时提供多种不同方式,将对象参数封送到本机代码。

作为特定的 COM 接口进行封送Marshalling as specific COM interfaces

如果 API 使用指向 COM 对象的指针,则可以使用类型为 object 的参数上的以下任一 UnmanagedType 格式告知 .NET 作为这些特定接口进行封送:

  • IUnknown
  • IDispatch
  • IInspectable 此外,如果类型标记为 [ComVisible(true)],或如果要封送 object 类型,则可以使用 UnmanagedType.Interface 格式将对象作为类型的 COM 视图的 COM 可调用包装器进行封送。

封送到 VARIANTMarshalling to a VARIANT

如果本机 API 采用 Win32 VARIANT,则可以使用 object 参数上的 UnmanagedType.Struct 格式将对象作为 VARIANT 进行封送。如需了解 .NET 类型与 VARIANT 类型之间的映射,请参阅有关自定义 object 字段的文档。

自定义封送处理程序Custom marshalers

如果要将本机 COM 接口投影到其他托管类型,则可以使用 UnmanagedType.CustomMarshaler 格式和 ICustomMarshaler 的实现来提供自己的自定义封送处理代码。