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/InvokeThrowOnUnmappableChar=true
em um P/InvokeBestFitMapping=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 empacotamento de tempo de execução está desabilitado. Para demonstrar a aplicação manual desta orientação, estes exemplos usam [DllImport]
em oposição ao atributo [LibraryImport]
recomendado. O analisador com ID SYSLIB1054 fornece orientação adicional quando você usa [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