Partager via


Callback, exemple

Cet exemple montre comment passer des délégués vers une fonction non managée qui attend des pointeurs fonction. Un délégué est une classe qui peut contenir une référence à une méthode et qui équivaut à un pointeur fonction de type sécurisé.

RemarqueRemarque

Lorsque vous utilisez un délégué à l'intérieur d'un appel, le Common Language Runtime évite au délégué d'être récupéré par le garbage collector pendant la durée de cet appel.Cependant, si la fonction non managée stocke le délégué pour utilisation après que l'appel soit terminé, vous devez manuellement empêcher le garbage collection jusqu'à ce que la fonction non managée en ait terminé avec le délégué.Pour plus d'informations, consultez HandleRef, exemple et GCHandle, exemple.

L'exemple Callback utilise les fonctions non managées suivantes, illustrées avec leur déclaration de fonction d'origine :

  • TestCallBack exportée à partir de PinvokeLib.dll.

    void TestCallBack(FPTR pf, int value);
    
  • TestCallBack2 exportée à partir de PinvokeLib.dll.

    void TestCallBack2(FPTR2 pf2, char* value);
    

PinvokeLib.dll est une bibliothèque non managée personnalisée qui contient une implémentation pour les fonctions précédemment répertoriées.

Dans cet exemple, la classe LibWrap contient des prototypes managés pour les méthodes TestCallBack et TestCallBack2. Ces deux méthodes passent un délégué à une fonction de rappel sous la forme d'un paramètre. La signature du délégué doit correspondre à la signature de la méthode qu'il référence. Par exemple, les délégués FPtr et FPtr2 ont des signatures qui sont identiques aux méthodes DoSomething et DoSomething2.

Déclaration de prototypes


Public Delegate Function FPtr( ByVal value As Integer ) As Boolean
Public Delegate Function FPtr2( ByVal value As String[]) As Boolean

Public Class LibWrap
    ' Declares managed prototypes for unmanaged functions.
    Declare Sub TestCallBack Lib "..\LIB\PinvokeLib.dll" ( ByVal cb _
        As FPtr, ByVal value As Integer )

    Declare Sub TestCallBack2 Lib "..\LIB\PinvokeLib.dll" ( ByVal cb2 _
        As FPtr2, ByVal value As String[])
End Class
public delegate bool FPtr(int value);
public delegate bool FPtr2(string value);

public class LibWrap
{
    // Declares managed prototypes for unmanaged functions.
    [DllImport("..\\LIB\\PinvokeLib.dll")]
    public static extern void TestCallBack(FPtr cb, int value);

    [DllImport("..\\LIB\\PinvokeLib.dll")]
    public static extern void TestCallBack2(FPtr2 cb2, String value);
}
public delegate bool FPtr(int value);
public delegate bool FPtr2(String^ value);

public ref class LibWrap
{
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);
};

Fonctions d'appel

Public Class App
   Public Shared Sub Main()
        Dim cb As FPtr
        cb = AddressOf App.DoSomething
        Dim cb2 As FPtr2
        cb2 = AddressOf App.DoSomething2
        LibWrap.TestCallBack( cb, 99 )
        LibWrap.TestCallBack2( cb2, "abc" )
    End Sub 'Main

    Public Shared Function DoSomething( ByVal value As Integer ) As Boolean
        Console.WriteLine( ControlChars.CrLf + "Callback called with param: {0}", value )
        ' ...
        Return True
    End Function

    Public Shared Function DoSomething2( ByVal value As String[]) As Boolean
        Console.WriteLine( ControlChars.CrLf + "Callback called with param: {0}", value )
        ' ...
        Return True
    End Function
End Class
public class App
{
    public static void Main()
    {
        FPtr cb = new FPtr(App.DoSomething);
        LibWrap.TestCallBack(cb, 99);
        FPtr2 cb2 = new FPtr2(App.DoSomething2);
        LibWrap.TestCallBack2(cb2, "abc");
    }

    public static bool DoSomething(int value)
    {
        Console.WriteLine("\nCallback called with param: {0}", value);
        // ...
        return true;
    }

    public static bool DoSomething2( String value )
    {
        Console.WriteLine("\nCallback called with param: {0}", value);
        // ...
        return true;
    }
}
public ref class App
{
public:
    static void Main()
    {
        FPtr^ cb = gcnew FPtr(&App::DoSomething);
        LibWrap::TestCallBack(cb, 99);
        FPtr2^ cb2 = gcnew FPtr2(&App::DoSomething2);
        LibWrap::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;
    }
};

Voir aussi

Concepts

Exemples divers de marshaling

Types de données d'appel de code non managé

Création de prototypes dans du code managé