Nota
El acceso a esta página requiere autorización. Puede intentar iniciar sesión o cambiar directorios.
El acceso a esta página requiere autorización. Puede intentar cambiar los directorios.
Las convenciones de llamada describen los detalles de bajo nivel sobre cómo se pasan los argumentos de método y los valores devueltos entre el autor de la llamada y el método llamado.
Es importante que la convención de llamada no administrada declarada en una declaración P/Invoke coincida con la convención de llamada no administrada usada por la implementación nativa. Los desajustes en las convenciones de llamada no gestionadas provocan corrupción de datos y fallos críticos que requieren habilidades de depuración de bajo nivel para diagnosticar.
Convención de llamada predeterminada de la plataforma
La mayoría de las plataformas usan una convención de llamada canónica y una convención de llamada especificada explícitamente no es necesaria en la mayoría de los casos.
Para la arquitectura x86, la convención de llamada predeterminada es específica de la plataforma.
Stdcall
("llamada estándar") es la convención de llamada predeterminada en Windows x86 y la usan la mayoría de las API de Win32.
Cdecl
es la convención de llamada predeterminada en Linux x86. Los puertos de Windows de bibliotecas de código abierto que se originaron en Unix suelen usar la Cdecl
convención de llamada incluso en Windows x86. Es necesario especificar explícitamente la Cdecl
convención de llamada en declaraciones P/Invoke para la interoperabilidad con estas bibliotecas.
Para las arquitecturas que no son x86, tanto las convenciones de llamada Stdcall
como Cdecl
se tratan como la convención de llamada predeterminada de la plataforma canónica.
Especificación de convenciones de llamada en declaraciones P/Invoke administradas
Las convenciones de llamada se especifican mediante tipos en el System.Runtime.CompilerServices
espacio de nombres o sus combinaciones:
- CallConvCdecl
- CallConvFastcall
- CallConvMemberFunction
- CallConvStdcall
- CallConvSuppressGCTransition
- CallConvThiscall
Ejemplos de convenciones de llamada especificadas explícitamente:
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();
Especificación de convenciones de llamada en versiones anteriores de .NET
Las versiones de .NET Framework y .NET anteriores a .NET 5 se limitan a un subconjunto de convenciones de llamada que puede describir la enumeración CallingConvention.
Ejemplos de convenciones de llamada especificadas explícitamente:
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);