It turns out that this is not possible in .NET directly, but can be achieved by changing the code of the executable file. To create a C # method that can read a memory address, make the following changes to the mono source code:
Modify gc-internal.h to add
gpointer ves_icall_System_GCHandle_GetAddrOfObject (MonoObject *obj) MONO_INTERNAL;
Modify gc.c to add:
gpointer ves_icall_System_GCHandle_GetAddrOfObject (MonoObject *obj) { return (char*)obj; }
Modify GCHandle.cs to add:
MethodImplAttribute(MethodImplOptions.InternalCall)] private extern static IntPtr GetAddrOfObject(object obj); public static IntPtr AddrOfObject(object o) { IntPtr res = GetAddrOfObject(o); return res; }
Edit icall-def.h to add
ICALL(GCH_6, "GetAddrOfObject", ves_icall_System_GCHandle_GetAddrOfObject)
Note that they must be in order, so add it above the GetAddrOfPinnedObject line Rebuild
Finally, call it with C #
for (int i = 0; i < 100; i++) { object o = new object (); var ptr = GCHandle.AddrOfObject (o); Console.WriteLine ("Address: " + ptr.ToInt64().ToString ("x")); }
evolvedmicrobe Aug 21 '14 at 17:57 2014-08-21 17:57
source share