Marshaling du runtime désactivé

Lorsque l’attribut System.Runtime.CompilerServices.DisableRuntimeMarshallingAttribute est appliqué à un assembly, le runtime désactive la plupart de la prise en charge du marshaling des données entre les représentations managées et natives. Cet article décrit les fonctionnalités qui sont désactivées et la façon dont les types .NET sont mappés aux types natifs lorsque le marshaling est désactivé.

Scénarios dans lesquels le marshaling est désactivé

Lorsque DisableRuntimeMarshallingAttribute est appliqué à un assembly, il affecte les types P/Invokes et Delegate dans l’assembly, ainsi que tous les appels à des pointeurs de fonction non managée dans l’assembly. Il n’affecte pas les types P/Invoke ou de délégués d’interopérabilité définis dans d’autres assemblys. Il ne désactive pas non plus le marshaling pour la prise en charge COM Interop intégrée du runtime. La prise en charge COM Interop intégrée peut être activée ou désactivée par le biais d’un commutateur de fonctionnalité.

Fonctionnalités désactivées

Lorsque DisableRuntimeMarshallingAttribute est appliqué à un assembly, les attributs suivants n’ont aucun effet ou lèvent une exception :

  • LCIDConversionAttribute sur un P/Invoke ou un délégué
  • SetLastError=true sur un P/Invoke
  • ThrowOnUnmappableChar=true sur un P/Invoke
  • BestFitMapping=true sur un P/Invoke
  • Signatures de méthode d’argument variadique .NET (varargs)
  • Paramètres in, ref, out

Règles par défaut de marshaling des types courants

Lorsque le marshaling est désactivé, les règles de marshaling par défaut deviennent beaucoup plus simples. Ces règles sont décrites ci-dessous. Comme mentionné dans la documentation sur les bonnes pratiques d’interopérabilité, les types blittables sont des types avec la même disposition dans le code managé et natif et, par conséquent, ils ne nécessitent aucun marshaling. En outre, ces règles ne peuvent pas être personnalisées avec les outils mentionnés dans la documentation sur la personnalisation du marshaling des paramètres.

Mot clé C# Type .NET Type natif
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 n’a aucun effet sur le P/Invoke)
nint System.IntPtr intptr_t
nuint System.UIntPtr uintptr_t
System.Boolean bool
Type C# unmanaged défini par l’utilisateur sans champs avec LayoutKind.Auto Traité en tant que type blittable. Tout le marshaling de structs personnalisés est ignoré.
Tous les autres types absence de prise en charge

Exemples

L’exemple suivant montre certaines fonctionnalités qui sont activées ou désactivées lorsque le marshaling de runtime est désactivé. Pour montrer l’application manuelle de cette aide, ces exemples utilisent [DllImport] par opposition à l’attribut [LibraryImport] recommandé. L’analyseur avec l’ID SYSLIB1054 offre une aide supplémentaire quand vous utilisez [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