Callback のサンプル

更新 : 2007 年 11 月

このサンプルでは、関数ポインタを要求するアンマネージ関数にデリゲートを渡す方法を示します。デリゲートは、メソッドへの参照を保持できるクラスのことであり、タイプ セーフ関数ポインタまたはコールバック関数と等価です。

5zwkzwf4.alert_note(ja-jp,VS.90).gifメモ :

呼び出しの中でデリゲートを使用する場合、共通言語ランタイムは、呼び出しの間にデリゲートがガベージ コレクトされないように保護します。ただし、呼び出しが完了した後で使用するためにアンマネージ関数がデリゲートを格納する場合には、アンマネージ関数がデリゲートを終了するまでの間、手動でガベージ コレクションを防ぐ必要があります。詳細については、「HandleRef のサンプル」および「GCHandle のサンプル」を参照してください。

Callback のサンプルで使用するアンマネージ関数とその関数宣言を次に示します。

  • PinvokeLib.dll からエクスポートされる TestCallBack

    void TestCallBack(FPTR pf, int value);
    
  • PinvokeLib.dll からエクスポートされる TestCallBack2

    void TestCallBack2(FPTR2 pf2, char* value);
    

PinvokeLib.dll はカスタム アンマネージ ライブラリであり、上記の関数に関する実装を含みます。

このサンプルでは、LibWrap クラスには TestCallBack メソッドと TestCallBack2 メソッドに関するマネージ プロトタイプが含まれます。どちらのメソッドも、コールバック関数にパラメータとしてデリゲートを渡します。デリゲートのシグネチャは、その参照先メソッドのシグネチャと一致する必要があります。たとえば、デリゲートの FPtr と FPtr2 は、DoSomething メソッドおよび DoSomething2 メソッドと同じシグネチャを持ちます。

次のコード例のソース コードは、.NET Framework「プラットフォーム呼び出しの技術サンプル」で提供されています。

プロトタイプの宣言

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

関数の呼び出し

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

参照

概念

各種のマーシャリングのサンプル

プラットフォーム呼び出しのデータ型

マネージ コードでのプロトタイプの作成