Share via


GCHandle-Beispiel

Dieses Beispiel demonstriert die Übergabe eines verwalteten Objekts an eine nicht verwaltete Funktion, die einen LPARAM-Typ erwartet. Ein LPARAM-Typ ist ein Zeiger auf einen nicht verwalteten Parameter.

Das GCHandle-Beispiel verwendet die folgende nicht verwaltete Funktion, die zusammen mit ihrer ursprünglichen Funktionsdeklaration aufgeführt wird:

  • EnumWindows aus User32.dll exportiert.

    BOOL EnumWindows(WNDENUMPROC lpEnumFunc, LPARAM lParam);
    

In diesem Beispiel enthält die LibWrap-Klasse einen verwalteten Prototyp der EnumWindows-Methode. Als Parameter ersetzt die verwaltete Methode den CallBack-Delegaten für den WNDENUMPROC-Funktionszeiger und einen IntPtr-Zeiger für den LPARAM-Typ.

Die App-Klasse erstellt einen Handle für das verwaltete Objekt mithilfe der GCHandle.Alloc-Methode, die verhindert, dass das verwaltete Objekt erfasst wird. Ein Aufruf der EnumWindows-Methode übergibt den Delegaten und das verwaltete Objekt, wobei der Handle in IntPtr umgewandelt wird. Die nicht verwaltete Funktion gibt den Typ an den Aufrufer als Parameter der Rückruffunktion zurück.

Deklarieren von Prototypen

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

Aufrufen von Funktionen

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

Siehe auch

Konzepte

Verschiedene Marshallingbeispiele

Datentypen für den Plattformaufruf

Erstellen von Prototypen in verwaltetem Code