Deaktiviertes Runtime-Marshalling

Wenn das System.Runtime.CompilerServices.DisableRuntimeMarshallingAttribute-Attribut auf eine Assembly angewendet wird, deaktiviert die Runtime den Großteil der integrierten Unterstützung für das Daten-Marshalling zwischen verwalteten und nativen Darstellungen. In diesem Artikel werden die Features beschrieben, die deaktiviert sind, und wie .NET-Typen nativen Typen zugeordnet werden, wenn das Marshalling deaktiviert ist.

Szenarien mit deaktiviertem Marshalling

Wenn das DisableRuntimeMarshallingAttribute auf eine Assembly angewendet wird, wirkt sich dies auf P/Invokes- und Delegate-Typen in der Assembly sowie auf alle Aufrufe von nicht verwalteten Funktionszeigern in der Assembly aus. Dies wirkt sich nicht auf P/Invoke- oder Interop-Delegattypen aus, die in anderen Assemblys definiert sind. Außerdem wird das Marshalling für die integrierte COM-Interop-Unterstützung der Runtime nicht deaktiviert. Die integrierte COM-Interop-Unterstützung kann über einen Featureschalter aktiviert oder deaktiviert werden.

Deaktivierte Features

Wenn das DisableRuntimeMarshallingAttribute auf eine Assembly angewendet wird, haben die folgenden Attribute keine Auswirkung oder lösen eine Ausnahme aus:

  • LCIDConversionAttribute für einen P/Invoke oder einen Delegaten
  • SetLastError=true für einen P/Invoke
  • ThrowOnUnmappableChar=true für einen P/Invoke
  • BestFitMapping=true für einen P/Invoke
  • Methodensignaturen variadischer .NET-Argumente (varargs)
  • Parameter in, ref, out

Standardregeln für das Marshallen von häufig verwendeten Typen

Wenn Marshallen deaktiviert ist, ändern sich die Regeln für das Standard-Marshalling in wesentlich einfachere Regeln. Diese Regeln werden unten beschrieben. Wie in der Dokumentation zu bewährten Methoden für Interop erwähnt, sind für Blitting geeignete Typen Typen mit demselben Layout in verwaltetem und nativem Code, die daher kein Marshalling erfordern. Darüber hinaus können diese Regeln nicht mit den Tools angepasst werden, die in der Dokumentation zum Anpassen des Parameter-Marshallings erwähnt werden.

C#-Schlüsselwort .NET-Typ Nativer Typ
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 für P/Invoke hat keine Auswirkung)
nint System.IntPtr intptr_t
nuint System.UIntPtr uintptr_t
System.Boolean bool
Benutzerdefinierter C#-Typ unmanaged ohne Felder mit LayoutKind.Auto Wird als für Blitting geeigneter Typ behandelt. Das gesamte benutzerdefinierte Struktur-Marshalling wird ignoriert.
Alle anderen Typen nicht unterstützt

Beispiele

Das folgende Beispiel zeigt einige Features, die bei deaktiviertem Runtime-Marshalling aktiviert oder deaktiviert sind:

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