Hinweis
Für den Zugriff auf diese Seite ist eine Autorisierung erforderlich. Sie können versuchen, sich anzumelden oder das Verzeichnis zu wechseln.
Für den Zugriff auf diese Seite ist eine Autorisierung erforderlich. Sie können versuchen, das Verzeichnis zu wechseln.
In diesem Beispiel wird veranschaulicht, wie Delegaten an eine nicht verwaltete Funktion übergeben werden, die Funktionszeiger erwartet. Ein Delegat ist eine Klasse, die einen Verweis auf eine Methode enthalten kann und einem typsicheren Funktionszeiger oder einer Rückruffunktion entspricht.
Hinweis
Bei Verwendung eines Delegaten in einem Aufruf schützt die Common Language Runtime den Delegaten für die Dauer dieses Aufrufs vor der Garbage Collection. Wenn die nicht verwaltete Funktion jedoch den Delegaten speichert, um ihn nach dem Abschluss des Aufrufs zu verwenden, müssen Sie die Garbage Collection manuell verhindern, bis die nicht verwaltete Funktion mit dem Delegaten beendet wird. Weitere Informationen finden Sie im HandleRef-Beispiel und im GCHandle-Beispiel.
Im Rückrufbeispiel werden die folgenden nicht verwalteten Funktionen verwendet, die mit der ursprünglichen Funktionsdeklaration angezeigt werden:
TestCallBackExportiert aus PinvokeLib.dll.void TestCallBack(FPTR pf, int value);TestCallBack2Exportiert aus PinvokeLib.dll.void TestCallBack2(FPTR2 pf2, char* value);
PinvokeLib.dll ist eine benutzerdefinierte nicht verwaltete Bibliothek, die eine Implementierung für die zuvor aufgeführten Funktionen enthält.
In diesem Beispiel enthält die NativeMethods Klasse verwaltete Prototypen für die TestCallBack und TestCallBack2 Methoden. Beide Methoden übergeben einen Delegaten als Parameter an eine Rückruffunktion. Die Signatur des Delegaten muss mit der Signatur der Methode übereinstimmen, auf die verwiesen wird. Beispielsweise verfügen die Delegierten FPtr und FPtr2 über Signaturen, die mit den Methoden DoSomething und DoSomething2 identisch sind.
Deklarieren von Prototypen
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
Aufrufen von Funktionen
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