Nuta
Dostęp do tej strony wymaga autoryzacji. Możesz spróbować się zalogować lub zmienić katalog.
Dostęp do tej strony wymaga autoryzacji. Możesz spróbować zmienić katalogi.
Konwencje wywoływania opisują szczegóły niskiego poziomu dotyczące sposobu przekazywania argumentów metody i zwracanych wartości między obiektem wywołującym a wywołaną metodą.
Ważne jest, aby niezarządzana konwencja wywoływania zadeklarowana w deklaracji P/Invoke była zgodna z niezarządzaną konwencją wywoływania używaną przez implementację natywną. Niezgodności w niezarządzanych konwencjach wywoływania mogą prowadzić do uszkodzenia danych i poważnych awarii, które wymagają umiejętności debugowania na niskim poziomie do skutecznej diagnozy.
Domyślna platformowa konwencja wywoływania
Większość platform korzysta z jednej kanonicznej konwencji wywoływania, dlatego w większości przypadków nie ma potrzeby jawnego określania konwencji wywoływania.
W przypadku architektury x86 domyślna konwencja wywoływania jest specyficzna dla platformy.
Stdcall ("wywołanie standardowe") jest domyślną konwencją wywoływania w systemie Windows x86 i jest używana przez większość interfejsów API Win32.
Cdecl to domyślna konwencja wywoływania w systemie Linux x86. Porty systemu Windows bibliotek typu open source pochodzące z systemu Unix często używają Cdecl konwencji wywoływania nawet w systemie Windows x86. Należy jawnie określić konwencję Cdecl wywoływania w deklaracjach P/Invoke na potrzeby współdziałania z tymi bibliotekami.
W przypadku architektur, które nie są x86, zarówno konwencje Stdcall, jak i Cdecl wywoływania są traktowane jako domyślna konwencja wywoływania platformy.
Określanie konwencji wywoływania w zarządzanych deklaracjach P/Invoke
Konwencje wywoływania są określane przez typy w System.Runtime.CompilerServices przestrzeni nazw lub ich kombinacje:
- CallConvCdecl
- CallConvFastcall
- CallConvMemberFunction
- CallConvStdcall
- CallConvSuppressGCTransition
- CallConvThiscall
Przykłady jawnie określonych konwencji wywoływania:
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();
Określanie konwencji wywoływania we wcześniejszych wersjach platformy .NET
Wersje .NET Framework i .NET wcześniejsze niż .NET 5 są ograniczone do podzestawu konwencji wywoływania, które mogą być opisane przez wyliczenie CallingConvention .
Przykłady jawnie określonych konwencji wywoływania:
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);