Nicht verwaltete Aufrufkonventionen

Aufrufkonventionen beschreiben Details auf niedriger Ebene, wie Methodenargumente und Rückgabewerte zwischen dem Aufrufer und der aufgerufenen Methode übergeben werden.

Es ist wichtig, dass die in einer P/Invoke-Deklaration deklarierte nicht verwaltete Aufrufkonvention mit der nicht verwalteten Aufrufkonvention übereinstimmt, die von der nativen Implementierung verwendet wird. Nichtübereinstimmungen in nicht verwalteten Aufrufkonventionen führen zu Datenbeschädigungen und schwerwiegenden Abstürzen, die zur Diagnose Debuggenfertigkeiten auf niedriger Ebene erfordern.

Plattform-Standardaufrufkonvention

Die meisten Plattformen verwenden eine kanonische Aufrufkonvention, und eine explizit angegebene Aufrufkonvention ist in den meisten Fällen nicht erforderlich.

Für die x86-Architektur ist die Standardaufrufkonvention plattformspezifisch. Stdcall („Standardaufruf") ist die Standardaufrufkonvention unter Windows x86 und wird von den meisten Win32-APIs verwendet. Cdecl ist die Standardaufrufkonvention unter Linux x86. Windows-Ports von Open-Source-Bibliotheken, die von Unix stammen, verwenden die Cdecl-Aufrufkonvention häufig auch unter Windows x86. Es ist erforderlich, die Cdecl-Aufrufkonvention in P/Invoke-Deklarationen für die Interoperabilität mit diesen Bibliotheken explizit anzugeben.

Bei Nicht-x86-Architekturen werden sowohl als Stdcall- als auch Cdecl-Aufrufkonventionen als kanonische Plattform-Standardaufrufkonvention behandelt.

Angeben von Aufrufkonventionen in verwalteten P/Invoke-Deklarationen

Die Aufrufkonventionen werden durch Typen im System.Runtime.CompilerServices-Namespace oder deren Kombinationen angegeben:

Beispiele für explizit angegebene Aufrufkonventionen:

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

Angeben von Aufrufkonventionen in früheren .NET-Versionen

.NET Framework und .NET-Versionen vor .NET 5 sind auf eine Teilmenge der Aufrufkonventionen beschränkt, die von der CallingConvention-Enumeration beschrieben werden können.

Beispiele für explizit angegebene Aufrufkonventionen:

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

Siehe auch