GCHandle のサンプル
更新 : 2007 年 11 月
このサンプルでは、LPARAM 型を要求するアンマネージ関数にマネージ オブジェクトを渡す方法を示します。LPARAM 型とは、アンマネージ パラメータへのポインタのことです。
GCHandle のサンプルで使用するアンマネージ関数とその関数宣言を次に示します。
User32.dll からエクスポートされる EnumWindows
BOOL EnumWindows(WNDENUMPROC lpEnumFunc, LPARAM lParam);
このサンプルでは、LibWrap クラスには EnumWindows メソッドのマネージ プロトタイプが含まれます。マネージ メソッドでは、パラメータとして WNDENUMPROC 関数の代わりに CallBack デリゲートが使用され、LPARAM 型の代わりに IntPtr ポインタが使用されます。
App クラスは、マネージ オブジェクトがコレクトされるのを防ぐ GCHandle.Alloc メソッドを使用して、マネージ オブジェクトを識別するハンドルを作成します。EnumWindows メソッドを呼び出すと、デリゲートとマネージ オブジェクトが渡され、IntPtr を識別するハンドルがキャストされます。アンマネージ関数は、コールバック関数のパラメータとして、型を呼び出し元に返します。
次のコード例のソース コードは、.NET Framework「プラットフォーム呼び出しの技術サンプル」で提供されています。
プロトタイプの宣言
Public Delegate Function CallBack( ByVal handle As Integer, ByVal param _As IntPtr ) As Boolean
Public Class LibWrap
' Passes a managed object instead of an LPARAM.
' Declares a managed prototype for the unmanaged function.
Declare Function EnumWindows Lib "user32.dll" ( _
ByVal cb As CallBack, ByVal param As IntPtr ) As Boolean
End Class 'LibWrap
public delegate bool CallBack( int handle, IntPtr param );
public class LibWrap
{
// Passes a managed object as an LPARAM type.
// Declares a managed prototype for the unmanaged function.
[ DllImport( "user32.dll" )]
public static extern bool EnumWindows( CallBack cb, IntPtr param );
}
関数の呼び出し
Public Class App
Public Shared Sub Main()
Dim tw As TextWriter = System.Console.Out
Dim gch As GCHandle = GCHandle.Alloc( tw )
' Platform invoke prevents the delegate from being garbage collected
' before the call ends.
Dim cewp As CallBack
cewp = AddressOf App.CaptureEnumWindowsProc
LibWrap.EnumWindows( cewp, GCHandle.op_Explicit( gch ))
gch.Free()
End Sub 'Main
Public Shared Function CaptureEnumWindowsProc( ByVal handle _
As Integer, ByVal param As IntPtr ) As Boolean
Dim gch As GCHandle = GCHandle.op_Explicit( param )
Dim tw As TextWriter = CType( gch.Target, TextWriter )
tw.WriteLine( handle )
return True
End Function 'CaptureEnumWindowsProc
End Class 'App
public class App
{
public static void Main()
{
TextWriter tw = System.Console.Out;
GCHandle gch = GCHandle.Alloc( tw );
CallBack cewp = new CallBack( CaptureEnumWindowsProc );
// Platform invoke prevents the delegate from being garbage
// collected before the call ends.
LibWrap.EnumWindows( cewp, (IntPtr)gch );
gch.Free();
}
private static bool CaptureEnumWindowsProc( int handle, IntPtr param )
{
GCHandle gch = (GCHandle)param;
TextWriter tw = (TextWriter)gch.Target;
tw.WriteLine( handle );
return true;
}
}