Sdílet prostřednictvím


Nespravované konvence volání

Konvence volání popisují podrobnosti o tom, jak se argumenty metody a návratové hodnoty předávají mezi volajícím a volanou metodou.

Je důležité, aby nespravovaná konvence volání deklarovaná v deklaraci P/Invoke odpovídala nespravované konvenci volání používané nativní implementací. Neshody v nespravovaných konvencích volání vedou k poškození dat a závažnému chybovému ukončení, které k diagnostice vyžadují dovednosti ladění nízké úrovně.

Výchozí konvence volání platformy

Většina platforem používá jednu kanonickou konvenci volání a explicitně zadaná konvence volání není ve většině případů nutná.

Výchozí konvence volání pro architekturu x86 je specifická pro platformu. Stdcall ("standardní volání") je výchozí konvence volání ve Windows x86 a používá ji většina rozhraní API Win32. Cdecl je výchozí konvence volání v Linuxu x86. Porty Windows opensourcových knihoven, které pocházejí ze systému Unix, často používají Cdecl konvenci volání i v systému Windows x86. Je nutné explicitně zadat Cdecl konvenci volání v deklaracích volání P/Invoke pro spolupráci s těmito knihovnami.

U architektur jiných StdcallCdecl než x86 se konvence volání považují za výchozí konvenci volání kanonické platformy.

Určení konvencí volání ve spravovaných deklarací volání nespravovaného volání

Konvence volání jsou určeny typy v System.Runtime.CompilerServices oboru názvů nebo jejich kombinace:

Příklady explicitně zadaných konvencí volání:

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

Určení konvencí volání ve starších verzích .NET

Verze rozhraní .NET Framework a .NET starší než .NET 5 jsou omezené na podmnožinu konvencí volání, které lze popsat výčtem CallingConvention .

Příklady explicitně zadaných konvencí volání:

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

Viz také