GCHandle 示例

更新:2007 年 11 月

该示例说明如何将托管对象传递给需要 LPARAM 类型的非托管函数。LPARAM 类型是指向非托管参数的指针。

GCHandle 示例使用以下非托管函数(这里同时显示其原始函数声明):

  • 从 User32.dll 导出的 EnumWindows

    BOOL EnumWindows(WNDENUMPROC lpEnumFunc, LPARAM lParam);
    

在该示例中,LibWrap 类包含 EnumWindows 方法的托管原型。作为其参数,该托管方法用 CallBack 委托替换 WNDENUMPROC 函数指针,并用 IntPtr 指针替换 LPARAM 类型。

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

请参见

概念

其他封送处理示例

平台调用数据类型

在托管代码中创建原型