Catatan
Akses ke halaman ini memerlukan otorisasi. Anda dapat mencoba masuk atau mengubah direktori.
Akses ke halaman ini memerlukan otorisasi. Anda dapat mencoba mengubah direktori.
Sampel ini menunjukkan cara meneruskan delegasi ke fungsi yang tidak dikelola yang mengharapkan penunjuk fungsi. Delegasi adalah kelas yang dapat menyimpan referensi ke metode dan setara dengan penunjuk fungsi jenis aman atau fungsi panggilan balik.
Nota
Saat Anda menggunakan delegate di dalam sebuah panggilan, runtime bahasa umum (common language runtime) melindungi delegate agar tidak terkumpul sebagai sampah selama panggilan tersebut. Namun, jika fungsi yang tidak dikelola menyimpan delegasi untuk digunakan setelah panggilan selesai, Anda harus secara manual mencegah pengumpulan sampah sampai fungsi yang tidak dikelola selesai dengan delegasi. Untuk informasi selengkapnya, lihat Sampel HandleRef dan Sampel GCHandle.
Sampel Panggilan balik menggunakan fungsi tidak terkelola berikut, yang ditunjukkan dengan deklarasi fungsi aslinya:
TestCallBackdiekspor dari PinvokeLib.dll.void TestCallBack(FPTR pf, int value);TestCallBack2diekspor dari PinvokeLib.dll.void TestCallBack2(FPTR2 pf2, char* value);
PinvokeLib.dll adalah pustaka kustom yang tidak dikelola yang berisi implementasi untuk fungsi yang tercantum sebelumnya.
Dalam sampel ini, NativeMethods berisi prototipe yang dikelola untuk metode TestCallBack dan TestCallBack2. Kedua metode meneruskan deleget ke fungsi callback sebagai parameter. Tanda tangan delegasi harus cocok dengan tanda tangan metode yang direferensikannya. Misalnya, delegasi FPtr dan FPtr2 memiliki tanda tangan yang identik dengan metode DoSomething dan DoSomething2.
Mendeklarasikan Prototipe
public delegate bool FPtr(int value);
public delegate bool FPtr2(String^ value);
private ref class NativeMethods
{
public:
// Declares managed prototypes for unmanaged functions.
[DllImport("..\\LIB\\PinvokeLib.dll")]
static void TestCallBack(FPtr^ cb, int value);
[DllImport("..\\LIB\\PinvokeLib.dll")]
static void TestCallBack2(FPtr2^ cb2, String^ value);
};
public delegate bool FPtr(int value);
public delegate bool FPtr2(string value);
internal static class NativeMethods
{
// Declares managed prototypes for unmanaged functions.
[DllImport("..\\LIB\\PinvokeLib.dll", CallingConvention = CallingConvention.Cdecl)]
internal static extern void TestCallBack(FPtr cb, int value);
[DllImport("..\\LIB\\PinvokeLib.dll", CallingConvention = CallingConvention.Cdecl)]
internal static extern void TestCallBack2(FPtr2 cb2, string value);
}
Public Delegate Function FPtr(ByVal value As Integer) As Boolean
Public Delegate Function FPtr2(ByVal value As String) As Boolean
Friend Class NativeMethods
' Declares managed prototypes for unmanaged functions.
<DllImport("..\LIB\PinvokeLib.dll", CallingConvention:=CallingConvention.Cdecl)>
Friend Shared Sub TestCallBack(
ByVal cb As FPtr, ByVal value As Integer)
End Sub
<DllImport("..\LIB\PinvokeLib.dll", CallingConvention:=CallingConvention.Cdecl)>
Friend Shared Sub TestCallBack2(
ByVal cb2 As FPtr2, ByVal value As String)
End Sub
End Class
Fungsi Panggilan
public ref class App
{
public:
static void Main()
{
FPtr^ cb = gcnew FPtr(&App::DoSomething);
NativeMethods::TestCallBack(cb, 99);
FPtr2^ cb2 = gcnew FPtr2(&App::DoSomething2);
NativeMethods::TestCallBack2(cb2, "abc");
}
static bool DoSomething(int value)
{
Console::WriteLine("\nCallback called with param: {0}", value);
// ...
return true;
}
static bool DoSomething2(String^ value)
{
Console::WriteLine("\nCallback called with param: {0}", value);
// ...
return true;
}
};
public class App
{
public static void Main()
{
FPtr cb = new FPtr(App.DoSomething);
NativeMethods.TestCallBack(cb, 99);
FPtr2 cb2 = new FPtr2(App.DoSomething2);
NativeMethods.TestCallBack2(cb2, "abc");
}
public static bool DoSomething(int value)
{
Console.WriteLine($"\nCallback called with param: {value}");
// ...
return true;
}
public static bool DoSomething2(string value)
{
Console.WriteLine($"\nCallback called with param: {value}");
// ...
return true;
}
}
Public Class App
Public Shared Sub Main()
Dim cb As FPtr = AddressOf App.DoSomething
Dim cb2 As FPtr2 = AddressOf App.DoSomething2
NativeMethods.TestCallBack(cb, 99)
NativeMethods.TestCallBack2(cb2, "abc")
End Sub
Public Shared Function DoSomething(ByVal value As Integer) As Boolean
Console.WriteLine(ControlChars.CrLf + $"Callback called with param: {value}")
' ...
Return True
End Function
Public Shared Function DoSomething2(ByVal value As String) As Boolean
Console.WriteLine(ControlChars.CrLf + $"Callback called with param: {value}")
' ...
Return True
End Function
End Class