Nota
L'accesso a questa pagina richiede l'autorizzazione. È possibile provare ad accedere o modificare le directory.
L'accesso a questa pagina richiede l'autorizzazione. È possibile provare a modificare le directory.
Le convenzioni di chiamata descrivono i dettagli di basso livello per il modo in cui gli argomenti del metodo e i valori restituiti vengono passati tra il chiamante e il metodo chiamato.
È importante che la convenzione di chiamata non gestita dichiarata in una dichiarazione P/Invoke corrisponda alla convenzione di chiamata non gestita usata dall'implementazione nativa. Le mancate corrispondenze nelle convenzioni di chiamata non gestite causano danneggiamenti dei dati e arresti anomali irreversibili che richiedono competenze di debug di basso livello per la diagnosi.
Convenzione di chiamata predefinita della piattaforma
La maggior parte delle piattaforme usa una convenzione di chiamata canonica e una convenzione di chiamata specificata in modo esplicito non è necessaria nella maggior parte dei casi.
Per l'architettura x86, la convenzione di chiamata predefinita è specifica della piattaforma.
Stdcall ("chiamata standard") è la convenzione di chiamata predefinita in Windows x86 e viene usata dalla maggior parte delle API Win32.
Cdecl è la convenzione di chiamata predefinita in Linux x86. Le porte Windows delle librerie open source che hanno origine in Unix spesso usano la Cdecl convenzione di chiamata anche in Windows x86. È necessario specificare in modo esplicito la Cdecl convenzione di chiamata nelle dichiarazioni P/Invoke per l'interoperabilità con queste librerie.
Per le architetture non x86, sia Stdcall sia Cdecl le convenzioni di chiamata vengono considerate come convenzioni di chiamata predefinite della piattaforma canonica.
Specificare le convenzioni di chiamata nelle dichiarazioni gestite P/Invoke
Le convenzioni di chiamata vengono specificate dai tipi nello spazio dei nomi System.Runtime.CompilerServices o dalle relative combinazioni.
- CallConvCdecl
- CallConvFastcall
- CallConvMemberFunction
- CallConvStdcall
- CallConvSuppressGCTransition
- CallConvThiscall
Esempi di convenzioni di chiamata specificate in modo esplicito:
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();
Specifica delle convenzioni di chiamata nelle versioni precedenti di .NET
Le versioni di .NET Framework e .NET precedenti a .NET 5 sono limitate a un subset di convenzioni di chiamata che possono essere descritte dall'enumerazione CallingConvention .
Esempi di convenzioni di chiamata specificate in modo esplicito:
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);