Customizing parameter marshaling
When the .NET runtime's default parameter marshaling behavior doesn't do what you want, use can use the System.Runtime.InteropServices.MarshalAsAttribute attribute to customize how your parameters are marshaled.
Customizing string parameters
.NET has a variety of formats for marshaling strings. These methods are split into distinct sections on C-style strings and Windows-centric string formats.
Each of these formats passes a null-terminated string to native code. They differ by the encoding of the native string.
The UnmanagedType.VBByRefStr format is slightly different. Like
LPWStr, it marshals the string to a native C-style string encoded in UTF-16. However, the managed signature has you pass in the string by reference and the matching native signature takes the string by value. This distinction allows you to use a native API that takes a string by value and modifies it in-place without having to use a
StringBuilder. We recommend against manually using this format since it's prone to cause confusion with the mismatching native and managed signatures.
Windows-centric string formats
When interacting with COM or OLE interfaces, you'll likely find that the native functions take strings as
BSTR arguments. You can use the UnmanagedType.BStr unmanaged type to marshal a string as a
If you're interacting with WinRT APIs, you can use the UnmanagedType.HString format to marshal a string as an
Customizing array parameters
.NET also provides you multiple ways to marshal array parameters. If you're calling an API that takes a C-style array, use the UnmanagedType.LPArray unmanaged type. If the values in the array need customized marshaling, you can use the ArraySubType field on the
[MarshalAs] attribute for that.
If you're using COM APIs, you'll likely have to marshal your array parameters as
SAFEARRAY*s. To do so, you can use the UnmanagedType.SafeArray unmanaged type. The default type of the elements of the
SAFEARRAY can be seen in the table on customizing
object fields. You can use the MarshalAsAttribute.SafeArraySubType and MarshalAsAttribute.SafeArrayUserDefinedSubType fields to customize the exact element type of the
Customizing boolean or decimal parameters
For information on marshaling boolean or decimal parameters, see Customizing structure marshaling.
Customizing object parameters (Windows-only)
On Windows, the .NET runtime provides a number of different ways to marshal object parameters to native code.
Marshaling as specific COM interfaces
If your API takes a pointer to a COM object, you can use any of the following
UnmanagedType formats on an
object-typed parameter to tell .NET to marshal as these specific interfaces:
Additionally, if your type is marked
[ComVisible(true)] or you're marshaling the
object type, you can use the UnmanagedType.Interface format to marshal your object as a COM callable wrapper for the COM view of your type.
Marshaling to a
If your native API takes a Win32
VARIANT, you can use the UnmanagedType.Struct format on your
object parameter to marshal your objects as
VARIANTs. See the documentation on customizing
object fields for a mapping between .NET types and
If you want to project a native COM interface into a different managed type, you can use the
UnmanagedType.CustomMarshaler format and an implementation of ICustomMarshaler to provide your own custom marshaling code.