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/InvokeThrowOnUnmappableChar=true
en un tipo P/InvokeBestFitMapping=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