using System; using System.Runtime.InteropServices; namespace VIVE.OpenXR { public static class MemoryTools { /// /// Convert the enum array to IntPtr. Should call after use. /// /// /// /// public static IntPtr ToIntPtr(T[] array) where T : Enum { int size = Marshal.SizeOf(typeof(T)) * array.Length; IntPtr ptr = Marshal.AllocHGlobal(size); int[] intArray = new int[array.Length]; for (int i = 0; i < array.Length; i++) intArray[i] = (int)(object)array[i]; Marshal.Copy(intArray, 0, ptr, array.Length); return ptr; } /// /// Make the same size raw buffer from input array. /// /// Data type could be primitive type or struct. Should call after use. /// The data array /// The memory handle. Should release by public static IntPtr MakeRawMemory(T[] refArray) { int size = Marshal.SizeOf(typeof(T)) * refArray.Length; return Marshal.AllocHGlobal(size); } /// /// Copy the raw memory to the array. You should make sure the array has the same size as the raw memory. /// /// Convert the memory to this type array. /// The output array. /// The data source in raw memory form. /// Specify the copy count. Count should be less than array length. public static void CopyFromRawMemory(T[] array, IntPtr raw, int count = 0) { int N = array.Length; if (count > 0 && count < array.Length) N = count; int step = Marshal.SizeOf(typeof(T)); for (int i = 0; i < N; i++) { array[i] = Marshal.PtrToStructure(IntPtr.Add(raw, i * step)); } } /// /// Make the same size raw buffer from input array. Make sure the raw has enough size. /// /// Convert this type array to raw memory. /// The output data in raw memory form /// The data source public static void CopyToRawMemory(IntPtr raw, T[] array) { int step = Marshal.SizeOf(typeof(T)); for (int i = 0; i < array.Length; i++) { Marshal.StructureToPtr(array[i], IntPtr.Add(raw, i * step), false); } } /// /// Release the raw memory handle which is created by /// /// public static void ReleaseRawMemory(IntPtr ptr) { Marshal.FreeHGlobal(ptr); } } }