Megjegyzés
Az oldalhoz való hozzáféréshez engedély szükséges. Megpróbálhat bejelentkezni vagy módosítani a címtárat.
Az oldalhoz való hozzáféréshez engedély szükséges. Megpróbálhatja módosítani a címtárat.
A hívási konvenciók a metódusargumentumok és a visszatérési értékek hívó és hívott metódus közötti átadásának alacsony szintű részleteit ismertetik.
Fontos, hogy a P/Invoke deklarációban deklarált nem felügyelt hívási konvenció megegyezik a natív implementáció által használt nem felügyelt hívási konvencióval. A nem felügyelt hívási konvenciók eltérései adatsérülésekhez és végzetes összeomlásokhoz vezetnek, amelyek diagnosztizálásához alacsony szintű hibakeresési készségekre van szükség.
Platform alapértelmezett hívási konvenció
A legtöbb platform egy hívó konvenciót használ, és a legtöbb esetben szükségtelen egy kifejezetten meghatározott hívási konvenció.
Az x86-os architektúra esetében az alapértelmezett hívási konvenció platformspecifikus.
Stdcall ("standard hívás") a Windows x86 alapértelmezett hívási konvenciója, amelyet a legtöbb Win32 API használ.
Cdecl Az alapértelmezett hívási konvenció Linux x86-on. Windows Unix-ból származó nyílt forráskódú kódtárak portjai gyakran használják a Cdecl hívási konvencióját még Windows x86-on is. Kifejezetten meg kell adni a hívási konvenciót a Cdecl P/Invoke deklarációkban az ezekkel a kódtárakkal való interopációhoz.
A nem x86-os architektúrák esetében mind a Stdcall hívó konvenciók, mind Cdecl a canonical platform alapértelmezett hívási konvencióként lesznek kezelve.
Mikor kihagyhatja a hívási konvenciót
Az x64-, ARM- és ARM64-architektúrákon csak egy hívási konvenció létezik, ezért az egyik explicit megadása szükségtelen. Csak a Windows x86 (32 bites) célzásánál kell megadnia egy hívási konvencióciót, ahol Stdcall és Cdecl eltérőek.
- ✔️ Kifejezetten adja meg a hívási konvenciót, amikor a Windows x86-ot célozza meg.
- ✔️ A DO kihagyja az x64, ARM és ARM64 hívó konvencióját – az attribútumnak nincs hatása ezekre az architektúrákra.
Hívási konvenciók megadása felügyelt P/Invoke deklarációkban
A hívási konvenciók a névtérben lévő System.Runtime.CompilerServices típusok vagy azok kombinációi szerint vannak megadva:
- CallConvCdecl
- CallConvFastcall
- CallConvMemberFunction
- CallConvStdcall
- CallConvSuppressGCTransition
- CallConvThiscall
Példák explicit módon megadott hívási konvenciókra:
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();
Hívási konvenciók megadása korábbi .NET verziókban
.NET Keretrendszer és .NET 5. .NET előtti verziói a CallingConvention enumerálás által leírt hívási konvenciók egy részhalmazára korlátozódnak.
Példák explicit módon megadott hívási konvenciókra:
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);