Share via


GCHandle 範例

這個範例示範如何將 Managed 物件傳遞至預期 LPARAM 型別的 Unmanaged 函式。LPARAM 型別是 Unmanaged 參數的指標。

GCHandle 範例使用下列 Unmanaged 函式,顯示其原始函式宣告:

  • EnumWindows exported from User32.dll.

    BOOL EnumWindows(WNDENUMPROC lpEnumFunc, LPARAM lParam);
    

在這個範例中,LibWrap 類別包含 EnumWindows 方法的 Managed 原型。如同它的參數,Managed 方法會以 CallBack 委派代替 WNDENUMPROC 函式指標,並以 IntPtr 指標代替 LPARAM 型別。

App 類別會使用 GCHandle.Alloc 方法 (可避免 Managed 物件被收集),建立 Managed 物件的控制代碼。對 EnumWindows 方法的呼叫會傳遞委派和 Managed 物件,將控制代碼轉換為 IntPtr。Unmanaged 函式會將型別傳回呼叫端做為回呼函式的參數。

下列程式碼範例的原始程式碼是由 .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;
   }   
}

請參閱

概念

其他封送處理範例
平台叫用資料型別
在 Managed 程式碼中建立原型