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/InvokeThrowOnUnmappableChar=true
für einen P/InvokeBestFitMapping=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. Um die manuelle Anwendung dieser Anleitung zu veranschaulichen, verwenden diese Beispiele [DllImport]
im Gegensatz zu dem empfohlenen [LibraryImport]
-Attribut. Das Analysetool mit ID SYSLIB1054 bietet zusätzliche Anleitungen, wenn Sie [LibraryImport]
verwenden.
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