GCHandle Structure


The .NET API Reference documentation has a new home. Visit the .NET API Browser on docs.microsoft.com to see the new experience.

Provides a way to access a managed object from unmanaged memory.

Namespace:   System.Runtime.InteropServices
Assembly:  mscorlib (in mscorlib.dll)

public struct GCHandle


Gets a value indicating whether the handle is allocated.


Gets or sets the object this handle represents.


Retrieves the address of an object in a GCHandleType.Pinned handle.


Allocates a Normal handle for the specified object.

System_CAPS_pubmethodSystem_CAPS_staticAlloc(Object, GCHandleType)

Allocates a handle of the specified type for the specified object.


Determines whether the specified GCHandle object is equal to the current GCHandle object.(Overrides ValueType.Equals(Object).)


Releases a GCHandle.


Returns a new GCHandle object created from a handle to a managed object.


Returns an identifier for the current GCHandle object.(Overrides ValueType.GetHashCode().)


Gets the Type of the current instance.(Inherited from Object.)


Returns the internal integer representation of a GCHandle object.


Returns the fully qualified type name of this instance.(Inherited from ValueType.)

System_CAPS_puboperatorSystem_CAPS_staticEquality(GCHandle, GCHandle)

Returns a value indicating whether two GCHandle objects are equal.

System_CAPS_puboperatorSystem_CAPS_staticExplicit(GCHandle to IntPtr)

A GCHandle is stored using an internal integer representation.

System_CAPS_puboperatorSystem_CAPS_staticExplicit(IntPtr to GCHandle)

A GCHandle is stored using an internal integer representation.

System_CAPS_puboperatorSystem_CAPS_staticInequality(GCHandle, GCHandle)

Returns a value indicating whether two GCHandle objects are not equal.

The GCHandle structure is used with the GCHandleType enumeration to create a handle corresponding to any managed object. This handle can be one of four types: Weak, WeakTrackResurrection, Normal, or Pinned. When the handle has been allocated, you can use it to prevent the managed object from being collected by the garbage collector when an unmanaged client holds the only reference. Without such a handle, the object can be collected by the garbage collector before completing its work on behalf of the unmanaged client.

You can also use GCHandle to create a pinned object that returns a memory address to prevent the garbage collector from moving the object in memory.

When the handle goes out of scope you must explicitly release it by calling the Free method; otherwise, memory leaks may occur. When you free a pinned handle, the associated object will be unpinned and will become eligible for garbage collection, if there are no other references to it.

The following example shows an App class that creates a handle to a managed object using the GCHandle.Alloc method, which prevents the managed object from being collected. A call to the EnumWindows method passes a delegate and a managed object (both declared as managed types, but not shown), and casts the handle to an IntPtr. The unmanaged function passes the type back to the caller as a parameter of the callback function.

using System;
using System.IO;
using System.Threading;
using System.Windows.Forms;
using System.Runtime.InteropServices;
using System.Security.Permissions;

public delegate bool CallBack(int handle, IntPtr param);

public class LibWrap
	// passing managed object as LPARAM
	// BOOL EnumWindows(WNDENUMPROC lpEnumFunc, LPARAM lParam);

	public static extern bool EnumWindows(CallBack cb, IntPtr param);

public class App
	public static void Main()

        [SecurityPermission(SecurityAction.Demand, UnmanagedCode=true)]
	public static void Run()
		TextWriter tw = System.Console.Out;
		GCHandle gch = GCHandle.Alloc(tw);

		CallBack cewp = new CallBack(CaptureEnumWindowsProc);

		// platform invoke will prevent delegate to be garbage collected
		// before call ends

		LibWrap.EnumWindows(cewp, GCHandle.ToIntPtr(gch));

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

Universal Windows Platform
Available since 8
.NET Framework
Available since 1.1
Portable Class Library
Supported in: portable .NET platforms
Available since 2.0
Windows Phone Silverlight
Available since 7.0
Windows Phone
Available since 8.1

Any public static ( Shared in Visual Basic) members of this type are thread safe. Any instance members are not guaranteed to be thread safe.

Return to top