Observação
O acesso a essa página exige autorização. Você pode tentar entrar ou alterar diretórios.
O acesso a essa página exige autorização. Você pode tentar alterar os diretórios.
As convenções de chamada descrevem detalhes de baixo nível sobre como os argumentos do método e os valores retornados são passados entre o chamador e o método chamado.
É importante que a convenção de chamada não gerenciada declarada em uma declaração P/Invoke corresponda à convenção de chamada não gerenciada usada pela implementação nativa. Incompatibilidades em convenções de chamada não gerenciadas levam a corrupção de dados e falhas fatais que exigem habilidades de depuração de baixo nível para diagnosticar.
Convenção de chamada padrão da plataforma
A maioria das plataformas usa uma convenção de chamada canônica e uma convenção de chamada explicitamente especificada é desnecessária na maioria dos casos.
Para a arquitetura x86, a convenção de chamada padrão é específica da plataforma.
Stdcall ("chamada padrão") é a convenção de chamada padrão no Windows x86 e é usada pela maioria das APIs do Win32.
Cdecl é a convenção de chamada padrão no Linux x86. As versões para Windows de bibliotecas de código aberto originadas no Unix geralmente usam a convenção de chamada Cdecl mesmo no Windows x86. É necessário especificar explicitamente a Cdecl convenção de chamada em declarações P/Invoke para interoperabilidade com essas bibliotecas.
Para arquiteturas não x86, as convenções de chamada Stdcall e Cdecl são tratadas como a convenção de chamada padrão canônica da plataforma.
Especificando convenções de chamada em declarações P/Invoke gerenciadas
As convenções de chamada são especificadas por tipos no System.Runtime.CompilerServices namespace ou suas combinações:
- CallConvCdecl
- CallConvFastcall
- CallConvMemberFunction
- CallConvStdcall
- CallConvSuppressGCTransition
- CallConvThiscall
Exemplos de convenções de chamada especificadas explicitamente:
using System.Runtime.InteropServices;
using System.Runtime.CompilerServices;
// P/Invoke declaration using SuppressGCTransition calling convention.
[LibraryImport("kernel32.dll")]
[UnmanagedCallConv(CallConvs = new Type[] { typeof(CallConvSuppressGCTransition) })]
extern static ulong GetTickCount64();
// Unmanaged callback with Cdecl calling convention.
[UnmanagedCallersOnly(CallConvs = new Type[] { typeof(CallConvCdecl) })]
static unsafe int NativeCallback(void* context);
// Method returning function pointer with combination of Cdecl and MemberFunction calling conventions.
static unsafe delegate* unmanaged[Cdecl, MemberFunction]<int> GetHandler();
Especificando convenções de chamada em versões anteriores do .NET
As versões do .NET Framework e do .NET anteriores ao .NET 5 são limitadas a um subconjunto de convenções de chamada que pode ser descrito pela enumeração CallingConvention .
Exemplos de convenções de chamada especificadas explicitamente:
using System.Runtime.InteropServices;
// P/Invoke declaration using Cdecl calling convention
[DllImport("ucrtbase.dll", CallingConvention=CallingConvention.Cdecl)]
static void* malloc(UIntPtr size);
// Delegate marshalled as callback with Cdecl calling convention
[UnmanagedFunctionPointer(CallingConvention.Cdecl)]
delegate void Callback(IntPtr context);