Share via


GCHandle 샘플

이 샘플에서는 LPARAM 형식을 필요로 하는 관리되지 않는 함수에 관리되는 개체를 전달하는 방법을 보여 줍니다. LPARAM 형식은 관리되지 않는 매개 변수에 대한 포인터입니다.

GCHandle 샘플에서는 다음의 관리되지 않는 함수를 사용합니다. 이 함수는 원래의 함수 선언과 함께 표시되어 있습니다.

  • User32.dll에서 내보낸 EnumWindows

    BOOL EnumWindows(WNDENUMPROC lpEnumFunc, LPARAM lParam);
    

이 샘플에서, LibWrap 클래스에는 EnumWindows 메서드의 관리되는 프로토타입이 포함되어 있습니다. 관리되는 메서드에서는 해당 매개 변수로서 WNDENUMPROC 함수 포인터를 CallBack 대리자로 대체하고 LPARAM 형식을 IntPtr 포인터로 대체합니다.

App클래스에서는 관리되는 개체가 수집되지 않도록 하는 GCHandle.Alloc 메서드를 사용하여 관리되는 개체에 대한 핸들을 만듭니다. EnumWindows 메서드를 호출하면 대리자 및 관리되는 개체가 전달되며 이 핸들은 IntPtr로 캐스팅됩니다. 관리되지 않는 함수는 해당 형식을 콜백 함수의 매개 변수로 호출자에게 다시 전달합니다.

프로토타입 선언

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
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 delegate bool CallBack(int handle, IntPtr param);

public ref class LibWrap
{
public:
    // Passes a managed object as an LPARAM type.
    // Declares a managed prototype for the unmanaged function.
    [DllImport("user32.dll")]
    static 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

    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
End Class
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;
    }
}
public ref class App
{
public:
    static void Main()
    {
        TextWriter^ tw = System::Console::Out;
        GCHandle gch = GCHandle::Alloc(tw);
        CallBack^ cewp = gcnew 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;
    }
};

참고 항목

개념

기타 마샬링 샘플

플랫폼 호출 데이터 형식

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