Marshalling de runtime desabilitado

Quando o atributo System.Runtime.CompilerServices.DisableRuntimeMarshallingAttribute é aplicado a um assembly, o tempo de execução desativa a maioria do suporte interno para marshalling de dados entre representações gerenciadas e nativas. Este artigo descreve os recursos que estão desabilitados e como os tipos .NET são mapeados para tipos nativos quando o marshalling está desabilitado.

Cenários em que o marshalling está desabilitado

Quando o DisableRuntimeMarshallingAttribute é aplicado a um assembly, ele afeta os tipos P/Invokes e Delegate no assembly, bem como quaisquer chamadas para ponteiros de função não gerenciados no assembly. Ele não afeta nenhum tipo de delegado P/Invoke ou interoperabilidade definido em outros assemblies. Ele também não desabilita o marshalling para o suporte de interoperabilidade COM interno do runtime. O suporte de interoperabilidade COM integrado pode ser ativado ou desativado por meio de um switch de recursos.

Recursos desabilitados

Quando o DisableRuntimeMarshallingAttribute é aplicado a um assembly, os seguintes atributos não terão efeito ou lançarão uma exceção:

  • LCIDConversionAttribute em um P/Invoke ou em um delegado
  • SetLastError=true em um P/Invoke
  • ThrowOnUnmappableChar=true em um P/Invoke
  • BestFitMapping=true em um P/Invoke
  • Assinaturas de método de argumento variável .NET (varargs)
  • parâmetros in, ref, out

Regras padrão para tipos comuns de marshalling

Quando o marshaling está desabilitado, as regras de marshaling padrão mudam para regras muito mais simples. Essas regras são descritas abaixo. Conforme mencionado na documentação de práticas recomendadas de interoperabilidade, os tipos blittable são tipos com o mesmo layout em código gerenciado e nativo e, como tal, não requerem marshaling. Além disso, essas regras não podem ser personalizadas com as ferramentas mencionadas na documentação sobre personalização de marshaling de parâmetros.

Palavra-chave C# Tipo .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 no P/Invoke não tem efeito)
nint System.IntPtr intptr_t
nuint System.UIntPtr uintptr_t
System.Boolean bool
Tipo C# unmanaged definido pelo usuário sem campos com LayoutKind.Auto Tratado como um tipo blittable. Todo o marshalling de estrutura personalizado é ignorado.
Todos os outros tipos não compatível

Exemplos

O exemplo a seguir mostra alguns recursos que são habilitados ou desabilitados quando o marshalling de tempo de execução está desabilitado:

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