Conventions d’appel non managées

conventions d’appel décrire les détails de bas niveau pour savoir comment les arguments de méthode et les valeurs renvoyées sont passés entre l’appelant et la méthode appelée.

Il est important que la convention d’appel non managée déclarée dans une déclaration P/Invoke correspond à la convention d’appel non managée utilisée par l’implémentation native. Les incompatibilités dans les conventions d’appel non managées entraînent des altérations de données et des incidents irrécupérables qui nécessitent des compétences de débogage de bas niveau pour diagnostiquer.

Convention d’appel par défaut de la plateforme

La plupart des plateformes utilisent une convention d’appel canonique et une convention d’appel spécifiée explicitement n’est pas nécessaire dans la plupart des cas.

Pour l’architecture x86, la convention d’appel par défaut est spécifique à la plateforme. Stdcall (« appel standard ») est la convention d’appel par défaut sur Windows x86 et elle est utilisée par la plupart des API Win32. Cdecl est la convention d’appel par défaut sous Linux x86. Les ports Windows des bibliothèques open source provenant d’Unix utilisent souvent la convention d’appel Cdecl même sur Windows x86. Il est nécessaire de spécifier explicitement la convention d’appel Cdecl dans les déclarations P/Invoke pour l’interopérabilité avec ces bibliothèques.

Pour les architectures non x86, les conventions d’appel Stdcall et Cdecl sont traitées comme la convention d’appel par défaut de la plateforme canonique.

Spécification de conventions d’appel dans les déclarations P/Invoke gérées

Les conventions d’appel sont spécifiées par les types dans l’espace de noms System.Runtime.CompilerServices ou leurs combinaisons :

Exemples de conventions d’appel spécifiées explicitement :

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();

Spécification de conventions d’appel dans les versions antérieures de .NET

Les versions .NET Framework et .NET antérieures à .NET 5 sont limitées à un sous-ensemble de conventions d’appel qui peuvent être décrites par l’énumération CallingConvention.

Exemples de conventions d’appel spécifiées explicitement :

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);

Voir aussi