Callback, exemple

Mise à jour : novembre 2007

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é.

Remarque :

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.

Le code source pour les exemples de code suivants est fourni par Appel de plate-forme, exemple de technologie du .NET Framework.

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 'LibWrap
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 );   
}

Appel de fonctions

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 )
      …
   End Function 'DoSomething
   Public Shared Function DoSomething2( ByVal value As String ) As Boolean
      Console.WriteLine( ControlChars.CrLf + "Callback called with _
          param: {0}", value )
      …
   End Function 'DoSomething2
End Class 'App
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 );
      …
   }
   public static bool DoSomething2( String value )
   {
      Console.WriteLine( "\nCallback called with param: {0}", value );
      …
   }   
}

Voir aussi

Concepts

Exemples divers de marshaling

Types de données d'appel de plate-forme

Création de prototypes dans du code managé