Zakázané zařazování za běhu

Při použití atributu System.Runtime.CompilerServices.DisableRuntimeMarshallingAttribute na sestavení modul runtime zakáže většinu integrované podpory pro zařazování dat mezi spravovanými a nativními reprezentacemi. Tento článek popisuje vlastnosti, které jsou zakázané, a jak jsou typy .NET mapovány na nativní typy, když je zařazování zakázáno.

Scénáře, kdy je zařazování zakázané

DisableRuntimeMarshallingAttribute Když je aplikován na sestavení, ovlivňuje typy P/Invokes a Delegate v sestavení a také všechna volání ukazatelů funkcí na nespravované funkce v sestavení. Nemá vliv na žádné typy delegátů P/Invoke ani delegátů pro interoperabilitu definované v jiných sestaveních. Také nezakazuje maršálování pro vestavěnou podporu spolupráce s COM v modulu runtime. Integrovanou podporu COM lze povolit nebo zakázat prostřednictvím přepínače funkcí.

Zakázané funkce

Když je DisableRuntimeMarshallingAttribute aplikováno na sestavení, následující atributy nebudou mít žádný vliv nebo vyvolají výjimku:

  • LCIDConversionAttribute při použití P/Invoke nebo delegáta
  • SetLastError=true u P/Invoke
  • ThrowOnUnmappableChar=true u P/Invoke
  • BestFitMapping=true u P/Invoke
  • Podpisy metod s variadickými argumenty .NET (varargs)
  • in, ref, out parametry

Výchozí pravidla pro zařazování běžných typů

Když je marshalling zakázán, pravidla pro výchozí marshallování se změní na mnohem jednodušší. Tato pravidla jsou popsaná níže. Jak bylo zmíněno v dokumentaci k osvědčeným postupům pro spolupráci, typy blittable jsou typy se stejným rozložením ve spravovaném a nativním kódu a proto nevyžadují žádné zprostředkování. Tato pravidla se navíc nedají přizpůsobit pomocí nástrojů uvedených v dokumentaci k přizpůsobení zařazování parametrů.

Klíčové slovo jazyka C# Typ .NET Nativní 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 na P/Invoke nemá žádný efekt)
nint System.IntPtr intptr_t
nuint System.UIntPtr uintptr_t
System.Boolean bool
Typ jazyka C# unmanaged definovaný uživatelem bez polí LayoutKind.Auto Považováno za být typu blittable. Všechny přizpůsobené maršálování struktur jsou ignorovány.
Všechny ostatní typy nepodporovaný

Příklady

Následující příklad ukazuje některé funkce, které jsou povoleny nebo zakázány, když je zakázáno maršálování za běhu. K předvedení ručního použití těchto pokynů se tyto příklady používají [DllImport] místo doporučeného [LibraryImport] atributu. Analyzátor s ID SYSLIB1054 poskytuje další pokyny při použití [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