GC handles are wrappers that are used to keep references to managed objects in the unmanaged space and preventing the object from being disposed.
These are the C equivalents of the System.GCHandle structure.
There are two kinds of GCHandles that can be created:
To retrieve the target address of an object pointed to by a GCHandle you should use mono_gchandle_get_target.
For example, consider the following C code:
static MonoObject* o = NULL;
The object in `o' will *NOT* be scanned.
If you need to store an object in a C variable and prevent it from being collected, you need to acquire a GC handle for it.
guint32 handle = mono_gchandle_new (my_object, TRUE);
TRUE means the object will be pinned, so it won't move in memory when we'll use a moving GC. You can access the MonoObject* referenced by a handle with:
MonoObject* obj = mono_gchandle_get_target (handle);
When you don't need the handle anymore you need to call:
mono_gchandle_free (handle);
Note that if you assign a new object to the C var, you need to get a new handle, it's not enough to store a new object in the C var.
So code that looked like this:
static MonoObject* o = NULL; ... o = mono_object_new (...); /* use o */ ... /* when done to allow the GC to collect o */ o = NULL;
should now be changed to:
static guint32 o_handle; ... MonoObject *o = mono_object_new (...); o_handle = mono_gchandle_new (o, TRUE); /* use o or mono_gchandle_get_target (o_handle) */ ... /* when done to allow the GC to collect o */ mono_gchandle_free (o_handle);