Compartilhar via


Exemplo de retorno de chamada

Este exemplo demonstra como passar delegados para uma função não gerenciada esperando ponteiros de função.Um delegado é uma classe que pode conter uma referência a um método e é equivalente a um ponteiro de função de segurança de tipos ou uma função de retorno de chamada.

Observação:

Quando você usar um delegado dentro de uma telefonar, o common linguagem tempo de execução protege o delegado seja lixo coletado para a duração da telefonar.No entanto, se o não-gerenciado função armazena o delegado para depois da telefonar concluir, você deve evitar coleta de lixo manualmente até que a função não gerenciada seja concluída com o delegado.Para obter mais informações, consulte o Exemplo de HandleRef and Exemplo de GCHandle.

O exemplo de retorno de chamada utiliza as seguintes funções não gerenciadas, mostradas com sua declaração de função original:

  • TestCallBack exportados de PinvokeLib.dll.

    void TestCallBack(FPTR pf, int value);
    
  • TestCallBack2 exportados de PinvokeLib.dll.

    void TestCallBack2(FPTR2 pf2, char* value);
    

PinvokeLib.dll é uma biblioteca de não gerenciada personalizada que contém uma implementação para as funções listadas anteriormente.

Neste exemplo, a LibWrap classe contém protótipos gerenciado para o TestCallBack e TestCallBack2 métodos. sistema autônomo dois métodos passar um delegado para uma função de retorno de chamada sistema autônomo um parâmetro.A assinatura do delegado deve corresponder à assinatura do método que faz referência a ele.Por exemplo, a FPtr e FPtr2 delegados têm as assinaturas são idênticas do DoSomething e DoSomething2 métodos.

O código-fonte para os exemplos de código a seguir é fornecido pelo.NET estrutura Invocação de plataforma Tecnologia Exemplo.

Declaração de protótipos

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

Chamando funções

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 );
      …
   }   
}

Consulte também

Conceitos

Diversos exemplos de marshaling

Tipos de dados de invocação de plataforma

Criando protótipos em código gerenciado