Serialización en tiempo de ejecución deshabilitada

Cuando el atributo System.Runtime.CompilerServices.DisableRuntimeMarshallingAttribute se aplica a un ensamblado, el runtime deshabilita la mayoría de la compatibilidad integrada con la serialización de datos entre representaciones administradas y nativas. En este artículo se describen las características que se deshabilitan y cómo se asignan los tipos de .NET a los tipos nativos al deshabilitar la serialización.

Escenarios en los que la serialización está deshabilitada

Cuando se aplica DisableRuntimeMarshallingAttribute a un ensamblado, afecta a los tipos P/Invokes y Delegate del ensamblado, así como a las llamadas a punteros de función no administrada del ensamblado. No afecta a ningún tipo delegado P/Invoke o de interoperabilidad definido en otros ensamblados. Tampoco deshabilita la serialización en la compatibilidad integrada de interoperabilidad COM del runtime. La compatibilidad integrada de interoperabilidad COM se puede habilitar o deshabilitar mediante un modificador de características.

Características deshabilitadas

Cuando DisableRuntimeMarshallingAttribute se aplica a un ensamblado, los atributos siguientes no tienen ningún efecto ni inician una excepción:

  • LCIDConversionAttribute en un tipo P/Invoke o un delegado
  • SetLastError=true en un tipo P/Invoke
  • ThrowOnUnmappableChar=true en un tipo P/Invoke
  • BestFitMapping=true en un tipo P/Invoke
  • Firmas de método de argumento variádicas de .NET (varargs)
  • Parámetros in, ref, out

Reglas predeterminadas para serializar tipos comunes

Cuando la serialización está deshabilitada, las reglas de la serialización predeterminada cambian a reglas mucho más sencillas. Estas reglas se describen a continuación. Como se ha mencionado en la documentación de procedimientos recomendados de interoperabilidad, los tipos que pueden transferirse en bloque de bits son tipos con el mismo diseño en código administrado y nativo y, por tanto, no requieren ninguna serialización. Además, estas reglas no se pueden personalizar con las herramientas mencionadas en la documentación sobre la personalización de la serialización de parámetros.

Palabra clave de C# Tipo de .NET Tipo nativo
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 en P/Invoke no tiene ningún efecto)
nint System.IntPtr intptr_t
nuint System.UIntPtr uintptr_t
System.Boolean bool
Tipo C# unmanaged definido por el usuario sin campos con LayoutKind.Auto Se trata como un tipo que puede transferirse en bloque de bits. Se omite toda Personalización de la serialización de estructuras.
Todos los demás tipos no admitido

Ejemplos

En el ejemplo siguiente se muestran algunas características que están habilitadas o deshabilitadas cuando la serialización en tiempo de ejecución está deshabilitada. Para demostrar la aplicación manual de esta guía, estos ejemplos usan [DllImport] en lugar del atributo [LibraryImport] recomendado. El analizador con identificador SYSLIB1054 proporciona instrucciones adicionales al usar [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