Freigeben über


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 systemeigenen Implementierung verwendet wird. Fehlanpassungen bei nicht verwalteten Aufrufkonventionen führen zu Datenbeschädigungen und schwerwiegenden Abstürzen, die Diagnosefähigkeiten auf niedriger Ebene erfordern.

Standard-Aufrufkonvention der Plattform

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

Für die x86-Architektur ist die Standardanrufkonvention plattformspezifisch. Stdcall ("Standardaufruf") ist die Standardanrufkonvention für Windows x86 und wird von den meisten Win32-APIs verwendet. Cdecl ist die Standardanrufkonvention unter Linux x86. Windows Ports von Open-Source-Bibliotheken, die von Unix stammen, verwenden häufig die Cdecl Aufrufkonvention auch auf 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 die Stdcall- als auch die Cdecl-Aufrufkonventionen als kanonische Standardaufrufkonvention der Plattform behandelt.

Wenn Sie die Anrufkonvention weglassen können

Bei den x64-, ARM- und ARM64-Architekturen gibt es nur eine Aufrufkonvention, daher ist es nicht notwendig, diese explizit anzugeben. Sie müssen nur eine Anrufkonvention angeben, wenn sie auf Windows x86 (32-Bit) ausgerichtet ist, wobei sich Stdcall und Cdecl unterscheiden.

  • ✔️ Geben Sie die Aufrufkonvention explizit an, wenn sie auf Windows x86 ausgerichtet ist.
  • ✔️ Lassen Sie die Aufrufkonvention bei x64, ARM und ARM64 weg — das Attribut hat auf diesen Architekturen keinen Effekt.

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