Events
Mar 17, 9 PM - Mar 21, 10 AM
Join the meetup series to build scalable AI solutions based on real-world use cases with fellow developers and experts.
Register nowThis browser is no longer supported.
Upgrade to Microsoft Edge to take advantage of the latest features, security updates, and technical support.
When the System.Runtime.CompilerServices.DisableRuntimeMarshallingAttribute
attribute is applied to an assembly, the runtime disables most built-in support for data marshalling between managed and native representations. This article describes the features that are disabled and how .NET types map to native types when marshalling is disabled.
When the DisableRuntimeMarshallingAttribute
is applied to an assembly, it affects P/Invokes and Delegate types in the assembly, as well as any calls to unmanaged function pointers in the assembly. It does not affect any P/Invoke or interop delegate types defined in other assemblies. It also does not disable marshalling for the runtime's built-in COM interop support. The built-in COM interop support can be enabled or disabled through a feature switch.
When the DisableRuntimeMarshallingAttribute
is applied to an assembly, the following attributes will have no effect or throw an exception:
SetLastError=true
on a P/InvokeThrowOnUnmappableChar=true
on a P/InvokeBestFitMapping=true
on a P/Invokein
, ref
, out
parametersWhen marshalling is disabled, the rules for default marshalling change to much simpler rules. These rules are described below. As mentioned in the interop best practices documentation, blittable types are types with the same layout in managed and native code and as such do not require any marshalling. Additionally, these rules cannot be customized with the tools mentioned in the documentation on customizing parameter marshalling.
C# keyword | .NET Type | Native Type |
---|---|---|
byte |
System.Byte |
uint8_t |
sbyte |
System.SByte |
int8_t |
short |
System.Int16 |
int16_t |
ushort |
System.UInt16 |
uint16_t |
int |
System.Int32 |
int32_t |
uint |
System.UInt32 |
uint32_t |
long |
System.Int64 |
int64_t |
ulong |
System.UInt64 |
uint64_t |
char |
System.Char |
char16_t (CharSet on the P/Invoke has no effect) |
nint |
System.IntPtr |
intptr_t |
nuint |
System.UIntPtr |
uintptr_t |
System.Boolean |
bool |
|
User-defined C# unmanaged type with no fields with LayoutKind.Auto |
Treated as a blittable type. All customized struct marshalling is ignored. | |
All other types | unsupported |
The following example shows some features that are enabled or disabled when runtime marshalling is disabled. To demonstrate the manual application of this guidance, these examples use [DllImport]
as opposed to the recommended [LibraryImport]
attribute. The analyzer with ID SYSLIB1054 provides additional guidance when you use [LibraryImport]
.
using System.Runtime.InteropServices;
struct Unmanaged
{
int i;
}
[StructLayout(LayoutKind.Auto)]
struct AutoLayout
{
int i;
}
struct StructWithAutoLayoutField
{
AutoLayout f;
}
[UnmanagedFunctionPointer] // OK: UnmanagedFunctionPointer attribute is supported
public delegate void Callback();
[UnmanagedFunctionPointer(CallingConvention.Cdecl)] // OK: Specifying a calling convention is supported
public delegate void Callback2(int i); // OK: primitive value types are allowed
[DllImport("NativeLibrary", EntryPoint = "CustomEntryPointName")] // OK: Specifying a custom entry-point name is supported
public static extern void Import(int i);
[DllImport("NativeLibrary", CallingConvention = CallingConvention.Cdecl)] // OK: Specifying a custom calling convention is supported
public static extern void Import(int i);
[UnmanagedCallConv(new[] { typeof(CallConvCdecl) })] // OK: Specifying a custom calling convention is supported
[DllImport("NativeLibrary")]
public static extern void Import(int i);
[DllImport("NativeLibrary", EntryPoint = "CustomEntryPointName", CharSet = CharSet.Unicode, ExactSpelling = false)] // OK: Specifying a custom entry-point name and using CharSet-based lookup is supported
public static extern void Import(int i);
[DllImport("NativeLibrary")] // OK: Not explicitly specifying an entry-point name is supported
public static extern void Import(Unmanaged u); // OK: unmanaged type
[DllImport("NativeLibrary")] // OK: Not explicitly specifying an entry-point name is supported
public static extern void Import(StructWithAutoLayoutField u); // Error: unmanaged type with auto-layout field
[DllImport("NativeLibrary")]
public static extern void Import(Callback callback); // Error: managed types are not supported when runtime marshalling is disabled
.NET feedback
.NET is an open source project. Select a link to provide feedback:
Events
Mar 17, 9 PM - Mar 21, 10 AM
Join the meetup series to build scalable AI solutions based on real-world use cases with fellow developers and experts.
Register nowTraining
Module
Learn coding practices to help prevent the occurrence of NullReferenceException.