diff --git a/.openpublishing.redirection.json b/.openpublishing.redirection.json index 488ab37ccefbd..2b72bf416686a 100644 --- a/.openpublishing.redirection.json +++ b/.openpublishing.redirection.json @@ -2234,6 +2234,21 @@ "redirect_url": "/dotnet/standard/native-interop/index", "redirect_document_id": true }, + { + "source_path": "docs/standard/native-interop/customize-parameter-marshalling.md", + "redirect_url": "/dotnet/standard/native-interop/customize-parameter-marshaling", + "redirect_document_id": true + }, + { + "source_path": "docs/standard/native-interop/customize-struct-marshalling.md", + "redirect_url": "/dotnet/standard/native-interop/customize-struct-marshaling", + "redirect_document_id": true + }, + { + "source_path": "docs/standard/native-interop/type-marshalling.md", + "redirect_url": "/dotnet/standard/native-interop/type-marshaling", + "redirect_document_id": true + }, { "source_path": "docs/standard/parallel-programming/how-to-write-a-parallel-foreach-loop-with-thread-local-variables.md", "redirect_url": "/dotnet/standard/parallel-programming/how-to-write-a-parallel-foreach-loop-with-partition-local-variables", diff --git a/docs/framework/data/wcf/using-actions-to-implement-server-side-behavior.md b/docs/framework/data/wcf/using-actions-to-implement-server-side-behavior.md index 24c2f26b3abca..e9c60b7d14d06 100644 --- a/docs/framework/data/wcf/using-actions-to-implement-server-side-behavior.md +++ b/docs/framework/data/wcf/using-actions-to-implement-server-side-behavior.md @@ -40,7 +40,7 @@ OData Actions provide a way to implement a behavior that acts upon a resource re 3. Storing any results from Invoke() so they can be retrieved using GetResult() - The parameters may be passed as tokens. This is because it is possible to write a Data Service Provider that works with tokens that represent resources, if this is the case you may need to convert (marshal) these tokens into actual resources before dispatching to the actual action. After the parameter has been marshalled, it must be in an editable state so that any changes to the resource that occur when the action is invoked will be saved and written to disk. + The parameters may be passed as tokens. This is because it is possible to write a Data Service Provider that works with tokens that represent resources, if this is the case you may need to convert (marshal) these tokens into actual resources before dispatching to the actual action. After the parameter has been marshaled, it must be in an editable state so that any changes to the resource that occur when the action is invoked will be saved and written to disk. This interface requires two methods: Invoke and GetResult. Invoke invokes the delegate that implements the action’s behavior and GetResult returns the result of the action. diff --git a/docs/framework/net-native/migrating-your-windows-store-app-to-net-native.md b/docs/framework/net-native/migrating-your-windows-store-app-to-net-native.md index f2937e4942881..6bff73a151f84 100644 --- a/docs/framework/net-native/migrating-your-windows-store-app-to-net-native.md +++ b/docs/framework/net-native/migrating-your-windows-store-app-to-net-native.md @@ -239,7 +239,7 @@ Other unsupported interop features include: - - - Rarely used marshalling APIs: + Rarely used marshaling APIs: - - diff --git a/docs/standard/native-interop/best-practices.md b/docs/standard/native-interop/best-practices.md index 514a09c8cfec3..dd87453b78ae2 100644 --- a/docs/standard/native-interop/best-practices.md +++ b/docs/standard/native-interop/best-practices.md @@ -27,7 +27,7 @@ The guidance in this section applies to all interop scenarios. |---------|---------|----------------|---------| | | `true` | keep default | When this is explicitly set to false, failed HRESULT return values will be turned into exceptions (and the return value in the definition becomes null as a result).| | | `false` | depends on the API | Set this to true if the API uses GetLastError and use Marshal.GetLastWin32Error to get the value. If the API sets a condition that says it has an error, get the error before making other calls to avoid inadvertently having it overwritten.| -| | `CharSet.None`, which falls back to `CharSet.Ansi` behavior | Explicitly use `CharSet.Unicode` or `CharSet.Ansi` when strings or characters are present in the definition | This specifies marshalling behavior of strings and what `ExactSpelling` does when `false`. Note that `CharSet.Ansi` is actually UTF8 on Unix. _Most_ of the time Windows uses Unicode while Unix uses UTF8. See more information on the [documentation on charsets](./charset.md). | +| | `CharSet.None`, which falls back to `CharSet.Ansi` behavior | Explicitly use `CharSet.Unicode` or `CharSet.Ansi` when strings or characters are present in the definition | This specifies marshaling behavior of strings and what `ExactSpelling` does when `false`. Note that `CharSet.Ansi` is actually UTF8 on Unix. _Most_ of the time Windows uses Unicode while Unix uses UTF8. See more information on the [documentation on charsets](./charset.md). | | | `false` | `true` | Set this to true and gain a slight perf benefit as the runtime will not look for alternate function names with either an "A" or "W" suffix depending on the value of the `CharSet` setting ("A" for `CharSet.Ansi` and "W" for `CharSet.Unicode`). | ## String parameters @@ -38,7 +38,7 @@ Remember to mark the `[DllImport]` as `Charset.Unicode` unless you explicitly wa **❌ DO NOT** use `[Out] string` parameters. String parameters passed by value with the `[Out]` attribute can destabilize the runtime if the string is an interned string. See more information about string interning in the documentation for . -**❌ AVOID** `StringBuilder` parameters. `StringBuilder` marshalling *always* creates a native buffer copy. As such, it can be extremely inefficient. Take the typical scenario of calling a Windows API that takes a string: +**❌ AVOID** `StringBuilder` parameters. `StringBuilder` marshaling *always* creates a native buffer copy. As such, it can be extremely inefficient. Take the typical scenario of calling a Windows API that takes a string: 1. Create a SB of the desired capacity (allocates managed capacity) **{1}** 2. Invoke @@ -52,11 +52,11 @@ in another call but this still only saves *1* allocation. It's much better to us The other issue with `StringBuilder` is that it always copies the return buffer back up to the first null. If the passed back string isn't terminated or is a double-null-terminated string, your P/Invoke is incorrect at best. -If you *do* use `StringBuilder`, one last gotcha is that the capacity does **not** include a hidden null, which is always accounted for in interop. It's common for people to get this wrong as most APIs want the size of the buffer *including* the null. This can result in wasted/unnecessary allocations. Additionally, this gotcha prevents the runtime from optimizing `StringBuilder` marshalling to minimize copies. +If you *do* use `StringBuilder`, one last gotcha is that the capacity does **not** include a hidden null, which is always accounted for in interop. It's common for people to get this wrong as most APIs want the size of the buffer *including* the null. This can result in wasted/unnecessary allocations. Additionally, this gotcha prevents the runtime from optimizing `StringBuilder` marshaling to minimize copies. **✔️ CONSIDER** using `char[]`s from an `ArrayPool`. -For more information on string marshalling, see [Default Marshalling for Strings](../../framework/interop/default-marshaling-for-strings.md) and [Customizing string marshalling](customize-parameter-marshalling.md#customizing-string-parameters). +For more information on string marshaling, see [Default Marshaling for Strings](../../framework/interop/default-marshaling-for-strings.md) and [Customizing string marshaling](customize-parameter-marshaling.md#customizing-string-parameters). > __Windows Specific__ > For `[Out]` strings the CLR will use `CoTaskMemFree` by default to free strings or `SysStringFree` for strings that are marked @@ -69,7 +69,7 @@ as `UnmanagedType.BSTR`. ## Boolean parameters and fields -Booleans are easy to mess up. By default, a .NET `bool` is marshalled to a Windows `BOOL`, where it's a 4-byte value. However, the `_Bool`, and `bool` types in C and C++ are a *single* byte. This can lead to hard to track down bugs as half the return value will be discarded, which will only *potentially* change the result. For more for information on marshalling .NET `bool` values to C or C++ `bool` types, see the documentation on [customizing boolean field marshalling](customize-struct-marshalling.md#customizing-boolean-field-marshalling). +Booleans are easy to mess up. By default, a .NET `bool` is marshaled to a Windows `BOOL`, where it's a 4-byte value. However, the `_Bool`, and `bool` types in C and C++ are a *single* byte. This can lead to hard to track down bugs as half the return value will be discarded, which will only *potentially* change the result. For more for information on marshaling .NET `bool` values to C or C++ `bool` types, see the documentation on [customizing boolean field marshaling](customize-struct-marshaling.md#customizing-boolean-field-marshaling). ## GUIDs @@ -83,7 +83,7 @@ GUIDs are usable directly in signatures. Many Windows APIs take `GUID&` type ali ## Blittable types -Blittable types are types that have the same bit-level representation in managed and native code. As such they do not need to be converted to another format to be marshalled to and from native code, and as this improves performance they should be preferred. +Blittable types are types that have the same bit-level representation in managed and native code. As such they do not need to be converted to another format to be marshaled to and from native code, and as this improves performance they should be preferred. **Blittable types:** @@ -122,7 +122,7 @@ You can see if a type is blittable by attempting to create a pinned `GCHandle`. For more information, see: - [Blittable and Non-Blittable Types](../../framework/interop/blittable-and-non-blittable-types.md) -- [Type Marshalling](type-marshalling.md) +- [Type Marshaling](type-marshaling.md) ## Keeping managed objects alive @@ -206,7 +206,7 @@ A Windows `PVOID` which is a C `void*` can be marshaled as either `IntPtr` or `U Managed structs are created on the stack and aren't removed until the method returns. By definition then, they are "pinned" (it won't get moved by the GC). You can also simply take the address in unsafe code blocks if native code won't use the pointer past the end of the current method. -Blittable structs are much more performant as they can simply be used directly by the marshalling layer. Try to make structs blittable (for example, avoid `bool`). For more information, see the [Blittable Types](#blittable-types) section. +Blittable structs are much more performant as they can simply be used directly by the marshaling layer. Try to make structs blittable (for example, avoid `bool`). For more information, see the [Blittable Types](#blittable-types) section. *If* the struct is blittable, use `sizeof()` instead of `Marshal.SizeOf()` for better performance. As mentioned above, you can validate that the type is blittable by attempting to create a pinned `GCHandle`. If the type is not a string or considered blittable, `GCHandle.Alloc` will throw an `ArgumentException`. @@ -241,4 +241,4 @@ internal unsafe struct SYSTEM_PROCESS_INFORMATION } ``` -However, there are some gotchas with fixed buffers. Fixed buffers of non-blittable types won't be correctly marshalled, so the in-place array needs to be expanded out to multiple individual fields. Additionally, in .NET Framework and .NET Core before 3.0, if a struct containing a fixed buffer field is nested within a non-blittable struct, the fixed buffer field won't be correctly marshalled to native code. +However, there are some gotchas with fixed buffers. Fixed buffers of non-blittable types won't be correctly marshaled, so the in-place array needs to be expanded out to multiple individual fields. Additionally, in .NET Framework and .NET Core before 3.0, if a struct containing a fixed buffer field is nested within a non-blittable struct, the fixed buffer field won't be correctly marshaled to native code. diff --git a/docs/standard/native-interop/charset.md b/docs/standard/native-interop/charset.md index c10f073ee0e92..f8ed651112e4e 100644 --- a/docs/standard/native-interop/charset.md +++ b/docs/standard/native-interop/charset.md @@ -1,16 +1,16 @@ --- -title: Charsets and marshalling - .NET +title: Charsets and marshaling - .NET description: Learn how different values of CharSet can change how .NET marshals your data to native code. author: jkoritzinsky ms.author: jekoritz ms.date: 01/18/2019 --- -# Charsets and marshalling +# Charsets and marshaling -The way `char` values, `string` objects, and `System.Text.StringBuilder` objects are marshalled depends on the value of the `CharSet` field on either the P/Invoke or structure. You can set the `CharSet` of a P/Invoke by setting the field when declaring your P/Invoke. To set the `CharSet` for a structure, set the field on your struct declaration. When these attribute fields are not set, it is up to the language compiler to determine which `CharSet` to use. C# and VB use the charset by default. +The way `char` values, `string` objects, and `System.Text.StringBuilder` objects are marshaled depends on the value of the `CharSet` field on either the P/Invoke or structure. You can set the `CharSet` of a P/Invoke by setting the field when declaring your P/Invoke. To set the `CharSet` for a structure, set the field on your struct declaration. When these attribute fields are not set, it is up to the language compiler to determine which `CharSet` to use. C# and VB use the charset by default. -The following table shows a mapping between each charset and how a character or string is represented when marshalled with that charset: +The following table shows a mapping between each charset and how a character or string is represented when marshaled with that charset: | CharSet | Windows | Unix on .NET Core 2.2 and earlier | Mono and Unix on .NET Core 3.0 and later | |---------|--------------------|-----------------------------|------------------------------------------| diff --git a/docs/standard/native-interop/customize-parameter-marshalling.md b/docs/standard/native-interop/customize-parameter-marshaling.md similarity index 66% rename from docs/standard/native-interop/customize-parameter-marshalling.md rename to docs/standard/native-interop/customize-parameter-marshaling.md index a0fcb578400e2..d62c1e23f29e2 100644 --- a/docs/standard/native-interop/customize-parameter-marshalling.md +++ b/docs/standard/native-interop/customize-parameter-marshaling.md @@ -1,18 +1,18 @@ --- -title: Customizing parameter marshalling - .NET +title: Customizing parameter marshaling - .NET description: Learn how to customize how .NET marshals your parameters to a native representation. author: jkoritzinsky ms.author: jekoritz ms.date: 01/18/2019 --- -# Customizing parameter marshalling +# Customizing parameter marshaling -When the .NET runtime's default parameter marshalling behavior doesn't do what you want, use can use the attribute to customize how your parameters are marshaled. +When the .NET runtime's default parameter marshaling behavior doesn't do what you want, use can use the attribute to customize how your parameters are marshaled. ## Customizing string parameters -.NET has a variety of formats for marshalling strings. These methods are split into distinct sections on C-style strings and Windows-centric string formats. +.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. ### C-Style strings @@ -35,19 +35,19 @@ If you're interacting with WinRT APIs, you can use the unmanaged type. If the values in the array need customized marshalling, you can use the field on the `[MarshalAs]` attribute for that. +.NET also provides you multiple ways to marshal array parameters. If you're calling an API that takes a C-style array, use the unmanaged type. If the values in the array need customized marshaling, you can use the 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 unmanaged type. The default type of the elements of the `SAFEARRAY` can be seen in the table on [customizing `object` fields](./customize-struct-marshalling.md#marshalling-systemobjects). You can use the and fields to customize the exact element type of the `SAFEARRAY`. +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 unmanaged type. The default type of the elements of the `SAFEARRAY` can be seen in the table on [customizing `object` fields](./customize-struct-marshaling.md#marshaling-systemobjects). You can use the and fields to customize the exact element type of the `SAFEARRAY`. ## Customizing boolean or decimal parameters -For information on marshalling boolean or decimal parameters, see [Customizing structure marshalling](customize-struct-marshalling.md). +For information on marshaling boolean or decimal parameters, see [Customizing structure marshaling](customize-struct-marshaling.md). ## Customizing object parameters (Windows-only) On Windows, the .NET runtime provides a number of different ways to marshal object parameters to native code. -### Marshalling as specific COM interfaces +### 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: @@ -55,12 +55,12 @@ If your API takes a pointer to a COM object, you can use any of the following `U - `IDispatch` - `IInspectable` -Additionally, if your type is marked `[ComVisible(true)]` or you're marshalling the `object` type, you can use the format to marshal your object as a COM callable wrapper for the COM view of your type. +Additionally, if your type is marked `[ComVisible(true)]` or you're marshaling the `object` type, you can use the format to marshal your object as a COM callable wrapper for the COM view of your type. -### Marshalling to a `VARIANT` +### Marshaling to a `VARIANT` -If your native API takes a Win32 `VARIANT`, you can use the format on your `object` parameter to marshal your objects as `VARIANT`s. See the documentation on [customizing `object` fields](customize-struct-marshalling.md#marshalling-systemobjects) for a mapping between .NET types and `VARIANT` types. +If your native API takes a Win32 `VARIANT`, you can use the format on your `object` parameter to marshal your objects as `VARIANT`s. See the documentation on [customizing `object` fields](customize-struct-marshaling.md#marshaling-systemobjects) for a mapping between .NET types and `VARIANT` types. ### Custom marshalers -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 to provide your own custom marshalling code. +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 to provide your own custom marshaling code. diff --git a/docs/standard/native-interop/customize-struct-marshalling.md b/docs/standard/native-interop/customize-struct-marshaling.md similarity index 84% rename from docs/standard/native-interop/customize-struct-marshalling.md rename to docs/standard/native-interop/customize-struct-marshaling.md index 3724653bc4cbd..d00cda03c49d0 100644 --- a/docs/standard/native-interop/customize-struct-marshalling.md +++ b/docs/standard/native-interop/customize-struct-marshaling.md @@ -1,5 +1,5 @@ --- -title: Customizing structure marshalling - .NET +title: Customizing structure marshaling - .NET description: Learn how to customize how .NET marshals your structures to a native representation. author: jkoritzinsky ms.author: jekoritz @@ -9,9 +9,9 @@ dev_langs: - "cpp" --- -# Customizing structure marshalling +# Customizing structure marshaling -Sometimes the default marshalling rules for structures aren't exactly what you need. The .NET runtimes provide a few extension points for you to customize your structure's layout and how fields are marshaled. +Sometimes the default marshaling rules for structures aren't exactly what you need. The .NET runtimes provide a few extension points for you to customize your structure's layout and how fields are marshaled. ## Customizing structure layout @@ -19,15 +19,15 @@ Sometimes the default marshalling rules for structures aren't exactly what you n **✔️ CONSIDER** using `LayoutKind.Sequential` whenever possible. -**✔️ DO** only use `LayoutKind.Explicit` in marshalling when your native struct is also has an explicit layout, such as a union. +**✔️ DO** only use `LayoutKind.Explicit` in marshaling when your native struct is also has an explicit layout, such as a union. -**❌ AVOID** using `LayoutKind.Explicit` when marshalling structures on non-Windows platforms. The .NET Core runtime doesn't support passing explicit structures by value to native functions on Intel or AMD 64-bit non-Windows systems. However, the runtime supports passing explicit structures by reference on all platforms. +**❌ AVOID** using `LayoutKind.Explicit` when marshaling structures on non-Windows platforms. The .NET Core runtime doesn't support passing explicit structures by value to native functions on Intel or AMD 64-bit non-Windows systems. However, the runtime supports passing explicit structures by reference on all platforms. -## Customizing boolean field marshalling +## Customizing boolean field marshaling Native code has many different boolean representations. On Windows alone, there are three ways to represent boolean values. The runtime doesn't know the native definition of your structure, so the best it can do is make a guess on how to marshal your boolean values. The .NET runtime provides a way to indicate how to marshal your boolean field. The following examples show how to marshal .NET `bool` to different native boolean types. -Boolean values default to marshalling as a native 4-byte Win32 [`BOOL`](/windows/desktop/winprog/windows-data-types#BOOL) value as shown in the following example: +Boolean values default to marshaling as a native 4-byte Win32 [`BOOL`](/windows/desktop/winprog/windows-data-types#BOOL) value as shown in the following example: ```csharp public struct WinBool @@ -97,9 +97,9 @@ struct VariantBool > [!NOTE] > `VARIANT_BOOL` is different than most bool types in that `VARIANT_TRUE = -1` and `VARIANT_FALSE = 0`. Additionally, all values that aren't equal to `VARIANT_TRUE` are considered false. -## Customizing array field marshalling +## Customizing array field marshaling -.NET also includes a few ways to customize array marshalling. +.NET also includes a few ways to customize array marshaling. By default, .NET marshals arrays as a pointer to a contiguous list of the elements: @@ -136,7 +136,7 @@ struct SafeArrayExample If you need to customize what type of element is in the `SAFEARRAY`, then you can use the and fields to customize the exact element type of the `SAFEARRAY`. -If you need to marshal the array in-place, you can use the value to tell the marshaler to marshal the array in-place. When you're using this marshalling, you also must supply a value to the field for the number of elements in the array so the runtime can correctly allocate space for the structure. +If you need to marshal the array in-place, you can use the value to tell the marshaler to marshal the array in-place. When you're using this marshaling, you also must supply a value to the field for the number of elements in the array so the runtime can correctly allocate space for the structure. ```csharp public struct InPlaceArray @@ -154,11 +154,11 @@ struct InPlaceArray ``` > [!NOTE] -> .NET doesn't support marshalling a variable length array field as a C99 Flexible Array Member. +> .NET doesn't support marshaling a variable length array field as a C99 Flexible Array Member. -## Customizing string field marshalling +## Customizing string field marshaling -.NET also provides a wide variety of customizations for marshalling string fields. +.NET also provides a wide variety of customizations for marshaling string fields. By default, .NET marshals a string as a pointer to a null-terminated string. The encoding depends on the value of the field in the . If no attribute is specified, the encoding defaults to an ANSI encoding. @@ -278,7 +278,7 @@ struct BString }; ``` -If your API requires you to pass the string in-place in the structure, you can use the value. Do note that the encoding for a string marshalled by `ByValTStr` is determined from the `CharSet` attribute. Additionally, it requires that a string length is passed by the field. +If your API requires you to pass the string in-place in the structure, you can use the value. Do note that the encoding for a string marshaled by `ByValTStr` is determined from the `CharSet` attribute. Additionally, it requires that a string length is passed by the field. ```csharp [StructLayout(LayoutKind.Sequential, CharSet = CharSet.Ansi)] @@ -312,7 +312,7 @@ struct DefaultString }; ``` -## Customizing decimal field marshalling +## Customizing decimal field marshaling If you're working on Windows, you might encounter some APIs that use the native [`CY` or `CURRENCY`](/windows/desktop/api/wtypes/ns-wtypes-tagcy) structure. By default, the .NET `decimal` type marshals to the native [`DECIMAL`](/windows/desktop/api/wtypes/ns-wtypes-tagdec) structure. However, you can use a with the value to instruct the marshaler to convert a `decimal` value to a native `CY` value. @@ -331,14 +331,14 @@ struct Currency }; ``` -## Marshalling `System.Object`s +## Marshaling `System.Object`s On Windows, you can marshal `object`-typed fields to native code. You can marshal these fields to one of three types: - [`VARIANT`](/windows/desktop/api/oaidl/ns-oaidl-tagvariant) - [`IUnknown*`](/windows/desktop/api/unknwn/nn-unknwn-iunknown) - [`IDispatch*`](/windows/desktop/api/oaidl/nn-oaidl-idispatch) -By default, an `object`-typed field will be marshalled to an `IUnknown*` that wraps the object. +By default, an `object`-typed field will be marshaled to an `IUnknown*` that wraps the object. ```csharp public struct ObjectDefault diff --git a/docs/standard/native-interop/index.md b/docs/standard/native-interop/index.md index ae8af085935a3..3be7a07e0e625 100644 --- a/docs/standard/native-interop/index.md +++ b/docs/standard/native-interop/index.md @@ -23,5 +23,5 @@ The previous list doesn't cover all of the potential situations and scenarios in ## See also - [Platform Invoke (P/Invoke)](pinvoke.md) -- [Type marshalling](type-marshalling.md) +- [Type marshaling](type-marshaling.md) - [Native interoperability best practices](best-practices.md) diff --git a/docs/standard/native-interop/pinvoke.md b/docs/standard/native-interop/pinvoke.md index c1ffb76a26560..fc8080fd84c84 100644 --- a/docs/standard/native-interop/pinvoke.md +++ b/docs/standard/native-interop/pinvoke.md @@ -173,7 +173,7 @@ namespace PInvokeSamples // The native callback takes a pointer to a struct. The below class // represents that struct in managed code. You can find more information - // about this in the section on marshalling below. + // about this in the section on marshaling below. [StructLayout(LayoutKind.Sequential)] public class StatClass { @@ -249,7 +249,7 @@ namespace PInvokeSamples } ``` -Both of the previous examples depend on parameters, and in both cases, the parameters are given as managed types. Runtime does the "right thing" and processes these into its equivalents on the other side. Learn about how types are marshalled to native code in our page on [Type marshalling](type-marshalling.md). +Both of the previous examples depend on parameters, and in both cases, the parameters are given as managed types. Runtime does the "right thing" and processes these into its equivalents on the other side. Learn about how types are marshaled to native code in our page on [Type marshaling](type-marshaling.md). ## More resources diff --git a/docs/standard/native-interop/type-marshalling.md b/docs/standard/native-interop/type-marshaling.md similarity index 61% rename from docs/standard/native-interop/type-marshalling.md rename to docs/standard/native-interop/type-marshaling.md index 46eb21995f6ff..247bfb4d2785f 100644 --- a/docs/standard/native-interop/type-marshalling.md +++ b/docs/standard/native-interop/type-marshaling.md @@ -1,27 +1,27 @@ --- -title: Type marshalling - .NET +title: Type marshaling - .NET description: Learn how .NET marshals your types to a native representation. author: jkoritzinsky ms.author: jekoritz ms.date: 01/18/2019 --- -# Type marshalling +# Type marshaling -**Marshalling** is the process of transforming types when they need to cross between managed and native code. +**Marshaling** is the process of transforming types when they need to cross between managed and native code. -Marshalling is needed because the types in the managed and unmanaged code are different. In managed code, for instance, you have a `String`, while in the unmanaged world strings can be Unicode ("wide"), non-Unicode, null-terminated, ASCII, etc. By default, the P/Invoke subsystem tries to do the right thing based on the default behavior, described on this article. However, for those situations where you need extra control, you can employ the [MarshalAs](xref:System.Runtime.InteropServices.MarshalAsAttribute) attribute to specify what is the expected type on the unmanaged side. For instance, if you want the string to be sent as a null-terminated ANSI string, you could do it like this: +Marshaling is needed because the types in the managed and unmanaged code are different. In managed code, for instance, you have a `String`, while in the unmanaged world strings can be Unicode ("wide"), non-Unicode, null-terminated, ASCII, etc. By default, the P/Invoke subsystem tries to do the right thing based on the default behavior, described on this article. However, for those situations where you need extra control, you can employ the [MarshalAs](xref:System.Runtime.InteropServices.MarshalAsAttribute) attribute to specify what is the expected type on the unmanaged side. For instance, if you want the string to be sent as a null-terminated ANSI string, you could do it like this: ```csharp [DllImport("somenativelibrary.dll")] static extern int MethodA([MarshalAs(UnmanagedType.LPStr)] string parameter); ``` -## Default rules for marshalling common types +## Default rules for marshaling common types -Generally, the runtime tries to do the "right thing" when marshalling to require the least amount of work from you. The following tables describe how each type is marshalled by default when used in a parameter or field. The C99/C++11 fixed-width integer and character types are used to ensure that the following table is correct for all platforms. You can use any native type that has the same alignment and size requirements as these types. +Generally, the runtime tries to do the "right thing" when marshaling to require the least amount of work from you. The following tables describe how each type is marshaled by default when used in a parameter or field. The C99/C++11 fixed-width integer and character types are used to ensure that the following table is correct for all platforms. You can use any native type that has the same alignment and size requirements as these types. -This first table describes the mappings for various types for whom the marshalling is the same for both P/Invoke and field marshalling. +This first table describes the mappings for various types for whom the marshaling is the same for both P/Invoke and field marshaling. | .NET Type | Native Type | |-----------|-------------------------| @@ -46,14 +46,14 @@ This first table describes the mappings for various types for whom the marshalli | `System.DateTime` | Win32 `DATE` type | | `System.Guid` | Win32 `GUID` type | -A few categories of marshalling have different defaults if you're marshalling as a parameter or structure. +A few categories of marshaling have different defaults if you're marshaling as a parameter or structure. | .NET Type | Native Type (Parameter) | Native Type (Field) | |-----------|-------------------------|---------------------| | .NET array | A pointer to the start of an array of native representations of the array elements. | Not allowed without a `[MarshalAs]` attribute| | A class with a `LayoutKind` of `Sequential` or `Explicit` | A pointer to the native representation of the class | The native representation of the class | -The following table includes the default marshalling rules that are Windows-only. On non-Windows platforms, you cannot marshal these types. +The following table includes the default marshaling rules that are Windows-only. On non-Windows platforms, you cannot marshal these types. | .NET Type | Native Type (Parameter) | Native Type (Field) | |-----------|-------------------------|---------------------| @@ -64,7 +64,7 @@ The following table includes the default marshalling rules that are Windows-only | `System.Collections.IEnumerable` | `IDispatch*` | Not allowed | | `System.DateTimeOffset` | `int64_t` representing the number of ticks since midnight on January 1, 1601 || `int64_t` representing the number of ticks since midnight on January 1, 1601 | -Some types can only be marshalled as parameters and not as fields. These types are listed in the following table: +Some types can only be marshaled as parameters and not as fields. These types are listed in the following table: | .NET Type | Native Type (Parameter Only) | |-----------|------------------------------| @@ -73,11 +73,11 @@ Some types can only be marshalled as parameters and not as fields. These types a | `System.Runtime.InteropServices.ArrayWithOffset` | `void*` | | `System.Runtime.InteropServices.HandleRef` | `void*` | -If these defaults don't do exactly what you want, you can customize how parameters are marshalled. The [parameter marshalling](customize-parameter-marshalling.md) article walks you through how to customize how different parameter types are marshalled. +If these defaults don't do exactly what you want, you can customize how parameters are marshaled. The [parameter marshaling](customize-parameter-marshaling.md) article walks you through how to customize how different parameter types are marshaled. -## Marshalling classes and structs +## Marshaling classes and structs -Another aspect of type marshalling is how to pass in a struct to an unmanaged method. For instance, some of the unmanaged methods require a struct as a parameter. In these cases, you need to create a corresponding struct or a class in managed part of the world to use it as a parameter. However, just defining the class isn't enough, you also need to instruct the marshaler how to map fields in the class to the unmanaged struct. Here the `StructLayout` attribute becomes useful. +Another aspect of type marshaling is how to pass in a struct to an unmanaged method. For instance, some of the unmanaged methods require a struct as a parameter. In these cases, you need to create a corresponding struct or a class in managed part of the world to use it as a parameter. However, just defining the class isn't enough, you also need to instruct the marshaler how to map fields in the class to the unmanaged struct. Here the `StructLayout` attribute becomes useful. ```csharp [DllImport("kernel32.dll")] @@ -117,4 +117,4 @@ typedef struct _SYSTEMTIME { } SYSTEMTIME, *PSYSTEMTIME*; ``` -Sometimes the default marshalling for your structure doesn't do what you need. The [Customizing structure marshalling](./customize-struct-marshalling.md) article teaches you how to customize how your structure is marshaled. +Sometimes the default marshaling for your structure doesn't do what you need. The [Customizing structure marshaling](./customize-struct-marshaling.md) article teaches you how to customize how your structure is marshaled. diff --git a/docs/toc.yml b/docs/toc.yml index bdfbf4556ed36..60c90fd92cdf3 100644 --- a/docs/toc.yml +++ b/docs/toc.yml @@ -108,15 +108,15 @@ items: - name: P/Invoke href: standard/native-interop/pinvoke.md - - name: Type marshalling - href: standard/native-interop/type-marshalling.md - - name: Customizing structure marshalling - href: standard/native-interop/customize-struct-marshalling.md - - name: Customizing parameter marshalling - href: standard/native-interop/customize-parameter-marshalling.md + - name: Type marshaling + href: standard/native-interop/type-marshaling.md + - name: Customizing structure marshaling + href: standard/native-interop/customize-struct-marshaling.md + - name: Customizing parameter marshaling + href: standard/native-interop/customize-parameter-marshaling.md - name: Interop guidance href: standard/native-interop/best-practices.md - - name: Charsets and marshalling + - name: Charsets and marshaling href: standard/native-interop/charset.md - name: Collections and Data Structures href: standard/collections/ diff --git a/includes/migration-guide/runtime/core/net-com-successfully-marshals-byref-safearray-parameters-on-events.md b/includes/migration-guide/runtime/core/net-com-successfully-marshals-byref-safearray-parameters-on-events.md index 2897b4065ab83..95cc8c3d8f651 100644 --- a/includes/migration-guide/runtime/core/net-com-successfully-marshals-byref-safearray-parameters-on-events.md +++ b/includes/migration-guide/runtime/core/net-com-successfully-marshals-byref-safearray-parameters-on-events.md @@ -2,8 +2,8 @@ | | | |---|---| -|Details|In the .NET Framework 4.7.2 and earlier versions, a ByRef [SafeArray](https://docs.microsoft.com/en-us/windows/desktop/api/oaidl/ns-oaidl-safearray) parameter on a COM event would fail to marshal back to native code. With this change the [SafeArray](https://docs.microsoft.com/en-us/windows/desktop/api/oaidl/ns-oaidl-safearray) is now marshalled successfully.
  • [ x ] Quirked
| -|Suggestion|If properly marshalling ByRef SafeArray parameters on COM Events breaks execution, you can disable this code by adding the following configuration switch to your application config:
<appSettings>
<add key="Switch.System.Runtime.InteropServices.DoNotMarshalOutByrefSafeArrayOnInvoke" value="true" />
</appSettings>
| +|Details|In the .NET Framework 4.7.2 and earlier versions, a ByRef [SafeArray](https://docs.microsoft.com/en-us/windows/desktop/api/oaidl/ns-oaidl-safearray) parameter on a COM event would fail to marshal back to native code. With this change the [SafeArray](https://docs.microsoft.com/en-us/windows/desktop/api/oaidl/ns-oaidl-safearray) is now marshaled successfully.
  • [ x ] Quirked
| +|Suggestion|If properly marshaling ByRef SafeArray parameters on COM Events breaks execution, you can disable this code by adding the following configuration switch to your application config:
<appSettings>
<add key="Switch.System.Runtime.InteropServices.DoNotMarshalOutByrefSafeArrayOnInvoke" value="true" />
</appSettings>
| |Scope|Minor| |Version|4.8| |Type|Runtime|