다음을 통해 공유


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 Platform Invoke 기술 샘플을 통해 제공됩니다.

프로토타입 선언

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

참고 항목

개념

기타 마샬링 샘플

플랫폼 호출 데이터 형식

관리 코드에서 프로토타입 만들기