Partager via


Conventions d’appel non managées

Les conventions d’appel décrivent les détails de bas niveau pour savoir comment les arguments de méthode et les valeurs de retour 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 sur Linux x86. Les ports Windows des bibliothèques open source provenant d’Unix utilisent souvent la Cdecl convention d’appel même sur Windows x86. Il est nécessaire de spécifier explicitement la Cdecl convention d’appel dans les déclarations P/Invoke pour l’interopérabilité avec ces bibliothèques.

Pour les architectures non x86, les conventions d’appel et Cdecl les Stdcall conventions d’appel 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 System.Runtime.CompilerServices de noms 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