Konvensi panggilan tidak terkelola

Konvensi panggilan menjelaskan detail tingkat rendah tentang bagaimana argumen metode dan nilai pengembalian diteruskan antara pemanggil dan metode yang disebut.

Penting bahwa konvensi panggilan yang tidak dikelola dideklarasikan dalam deklarasi P/Invoke cocok dengan konvensi panggilan yang tidak dikelola yang digunakan oleh implementasi asli. Ketidakcocokan dalam konvensi panggilan yang tidak dikelola menyebabkan kerusakan data dan crash fatal yang memerlukan keterampilan penelusuran kesalahan tingkat rendah untuk didiagnosis.

Konvensi panggilan default platform

Sebagian besar platform menggunakan satu konvensi panggilan kanonis dan konvensi panggilan yang ditentukan secara eksplisit tidak perlu dalam banyak kasus.

Untuk arsitektur x86, konvensi panggilan default adalah spesifik platform. Stdcall ("panggilan standar") adalah konvensi panggilan default pada Windows x86 dan digunakan oleh sebagian besar API Win32. Cdecl adalah konvensi panggilan default di Linux x86. Port Windows pustaka sumber terbuka yang berasal dari Unix sering menggunakan Cdecl konvensi panggilan bahkan pada Windows x86. Anda harus secara eksplisit menentukan Cdecl konvensi panggilan dalam deklarasi P/Panggil untuk interop dengan pustaka ini.

Untuk arsitektur non-x86, konvensi Stdcall panggilan dan Cdecl keduanya diperlakukan sebagai konvensi panggilan default platform kanonis.

Menentukan konvensi panggilan dalam deklarasi P/Panggil terkelola

Konvensi panggilan ditentukan oleh jenis di System.Runtime.CompilerServices namespace layanan atau kombinasinya:

Contoh konvensi panggilan yang ditentukan secara eksplisit:

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

Menentukan konvensi panggilan di versi .NET sebelumnya

Versi .NET Framework dan .NET sebelum .NET 5 terbatas pada subset konvensi panggilan yang dapat dijelaskan oleh enumerasi CallingConvention .

Contoh konvensi panggilan yang ditentukan secara eksplisit:

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

Lihat juga