This documentation is archived and is not being maintained.

GCHandle Sample

This sample demonstrates how to pass a managed object to an unmanaged function that expects an LPARAM type. An LPARAM type is a pointer to an unmanaged parameter.

The GCHandle sample uses the following unmanaged function, shown with its original function declaration:

  • EnumWindows exported from User32.dll.

    BOOL EnumWindows(WNDENUMPROC lpEnumFunc, LPARAM lParam);

In this sample, the LibWrap class contains a managed prototype of the EnumWindows method. As its parameters, the managed method substitutes the CallBack delegate for the WNDENUMPROC function pointer and an IntPtr pointer for the LPARAM type.

The App class creates a handle to the managed object using the GCHandle.Alloc method, which prevents the managed object from being collected. A call to the EnumWindows method passes the delegate and the managed object, casting the handle to an IntPtr. The unmanaged function passes the type back to the caller as a parameter of the callback function.

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.
    public static extern bool EnumWindows(CallBack cb, IntPtr param);

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

    private static bool CaptureEnumWindowsProc(int handle, IntPtr param)
        GCHandle gch = (GCHandle)param;
        TextWriter tw = (TextWriter)gch.Target;
        return true;