Bagikan melalui


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 pemanggilan yang tidak terkelola dapat menyebabkan kerusakan data dan crash fatal yang memerlukan keterampilan debugging tingkat rendah untuk mendiagnosis.

Konvensi panggilan platform bawaan

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. Versi Windows dari pustaka sumber terbuka yang berasal dari Unix sering kali menggunakan konvensi panggilan Cdecl dan juga pada sistem Windows x86. Anda harus secara eksplisit menentukan Cdecl konvensi panggilan dalam deklarasi P/Invoke untuk menggunakan pustaka ini.

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

Menentukan konvensi pemanggilan dalam deklarasi P/Invoke yang dikelola

Konvensi panggilan ditentukan oleh jenis di System.Runtime.CompilerServices namespace 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