/// <summary> /// Get <see cref="IntPtr"/> address from <typeparamref name="T"/> <paramref name="obj"/> /// with type <paramref name="pointerType"/> /// </summary> /// <typeparam name="T">Type of object</typeparam> /// <param name="obj">source object</param> /// <param name="pointerType">type of address</param> /// <returns><see cref="IntPtr"/> address with requested type</returns> public static IntPtr GetAddress <T>(this T obj, ObjectPointerTo pointerType) where T : class { if (obj == null) { return(IntPtr.Zero); } var finder = new FindAddressHelper <T> { Object = obj }; var addr = &finder.Address; IntPtr ptr = *(IntPtr *)&addr[-1]; switch (pointerType) { case ObjectPointerTo.MethodTablePointer: break; case ObjectPointerTo.Header: ptr = IntPtr.Add(ptr, -IntPtr.Size); break; case ObjectPointerTo.Data: ptr = IntPtr.Add(ptr, IntPtr.Size); break; default: throw new ArgumentException("Unknown type of requested address", nameof(pointerType)); } return(ptr); }
/// <summary> /// Cast <see cref="IntPtr"/> to <typeparamref name="TResult"/> /// </summary> /// <typeparam name="TResult">result type</typeparam> /// <param name="address">pointer to object</param> /// <param name="pointerType">address type</param> /// <returns>casted object</returns> public static TResult ToObject <TResult>(this IntPtr address, ObjectPointerTo pointerType) where TResult : class { var finder = new FindAddressHelper <TResult>(); var addr = &finder.Address; var ptr = address; if (ptr != IntPtr.Zero) { switch (pointerType) { case ObjectPointerTo.MethodTablePointer: break; case ObjectPointerTo.Header: ptr = IntPtr.Add(ptr, IntPtr.Size); break; case ObjectPointerTo.Data: ptr = IntPtr.Add(ptr, -IntPtr.Size); break; default: throw new ArgumentException("Unknown type of address", nameof(pointerType)); } } *(IntPtr *)&addr[-1] = ptr; return(finder.Object); }