Wyłączone marshaling środowiska uruchomieniowego
Po zastosowaniu atrybutu System.Runtime.CompilerServices.DisableRuntimeMarshallingAttribute
do zestawu środowisko uruchomieniowe wyłącza najbardziej wbudowaną obsługę marshalingu danych między zarządzanymi i natywnymi reprezentacjami. W tym artykule opisano funkcje, które są wyłączone i jak typy platformy .NET mapują się na typy natywne, gdy marshalling jest wyłączony.
Scenariusze, w których marshalling jest wyłączony
Zastosowanie elementu DisableRuntimeMarshallingAttribute
do zestawu wpływa na typy P/Invoke i Delegate w zestawie, a także wszelkie wywołania wskaźników funkcji niezarządzanych w zestawie. Nie ma to wpływu na żadne typy delegatów P/Invoke ani międzyoperajności zdefiniowane w innych zestawach. Nie wyłącza również marshalingu dla wbudowanej obsługi międzyoperacyjnej modelu COM środowiska uruchomieniowego. Wbudowana obsługa międzyoperaktywności modelu COM może być włączona lub wyłączona za pośrednictwem przełącznika funkcji.
Wyłączone funkcje
Po zastosowaniu DisableRuntimeMarshallingAttribute
elementu do zestawu następujące atrybuty nie będą miały żadnego wpływu ani nie będą zgłaszać wyjątku:
- LCIDConversionAttribute w elemecie P/Invoke lub pełnomocniku
SetLastError=true
na P/InvokeThrowOnUnmappableChar=true
na P/InvokeBestFitMapping=true
na P/Invoke- Sygnatury metod argumentów platformy .NET (varargs)
in
, ,ref
out
parametry
Domyślne reguły marshalingu typowych typów
Gdy marshalling jest wyłączony, reguły domyślne zmiany marshalingu na znacznie prostsze reguły. Te reguły zostały opisane poniżej. Jak wspomniano w dokumentacji najlepszych rozwiązań międzyoperacyjnych, typy blittable są typami o tym samym układzie w kodzie zarządzanym i natywnym, a w związku z tym nie wymagają żadnego marshallingu. Ponadto tych reguł nie można dostosować za pomocą narzędzi wymienionych w dokumentacji dotyczącej dostosowywania marshalingu parametrów.
Słowo kluczowe języka C# | Typ platformy .NET | Typ natywny |
---|---|---|
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 na P/Invoke nie ma wpływu) |
nint |
System.IntPtr |
intptr_t |
nuint |
System.UIntPtr |
uintptr_t |
System.Boolean |
bool |
|
Typ języka C# unmanaged zdefiniowany przez użytkownika bez pólLayoutKind.Auto |
Traktowany jako typ blittable. Wszystkie dostosowane marshalling struktury są ignorowane. | |
Wszystkie inne typy | Nieobsługiwane |
Przykłady
W poniższym przykładzie przedstawiono niektóre funkcje, które są włączone lub wyłączone, gdy marshalling środowiska uruchomieniowego jest wyłączony. Aby zademonstrować ręczne stosowanie tych wskazówek, te przykłady są używane [DllImport]
w przeciwieństwie do zalecanego [LibraryImport]
atrybutu. Analizator o identyfikatorze SYSLIB1054 zawiera dodatkowe wskazówki dotyczące korzystania z usługi [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