// -------------------------------------------------------------------------------------------------------------------- // // This file is part of the HandBrake source code - It may be used under the terms of the GNU General Public License. // // // Helper utilities for native interop. // // -------------------------------------------------------------------------------------------------------------------- namespace HandBrake.Interop { using System; using System.Collections.Generic; using System.Runtime.InteropServices; using HandBrake.Interop.HbLib; /// /// Helper utilities for native interop. /// public static class InteropUtilities { /// /// Reads the given native structure pointer. /// /// The type to convert the structure to. /// The pointer to the native structure. /// The converted structure. public static T ReadStructure(IntPtr structPtr) { return (T)Marshal.PtrToStructure(structPtr, typeof(T)); } /// /// Converts the given native HandBrake list to a managed list. /// /// The type of structure in the list. /// The pointer to the native list. /// The converted managed list. public static List ConvertList(IntPtr listPtr) { List returnList = new List(); hb_list_s itemList = ReadStructure(listPtr); for (int i = 0; i < itemList.items_count; i++) { IntPtr itemPtr = Marshal.ReadIntPtr(itemList.items, i * Marshal.SizeOf(typeof(IntPtr))); returnList.Add(ReadStructure(itemPtr)); } return returnList; } /// /// Creats a new, empty native HandBrake list. /// /// The capacity of the new list. /// The new native list. public static NativeList CreateNativeList(int capacity) { NativeList returnList = new NativeList(); int intSize = Marshal.SizeOf(typeof(IntPtr)); IntPtr nativeListInternal = Marshal.AllocHGlobal(capacity * intSize); returnList.AllocatedMemory.Add(nativeListInternal); hb_list_s nativeListStruct = new hb_list_s(); nativeListStruct.items = nativeListInternal; nativeListStruct.items_alloc = capacity; nativeListStruct.items_count = 0; IntPtr nativeListStructPtr = Marshal.AllocHGlobal(Marshal.SizeOf(typeof(hb_list_s))); Marshal.StructureToPtr(nativeListStruct, nativeListStructPtr, false); returnList.ListPtr = nativeListStructPtr; return returnList; } /// /// Creates a native HandBrake list from the given managed list of pointers. /// /// The managed list to convert. /// The converted native list. public static NativeList CreateIntPtrList(List list) { NativeList returnList = new NativeList(); int intSize = Marshal.SizeOf(typeof(IntPtr)); IntPtr nativeListInternal = Marshal.AllocHGlobal(list.Count * intSize); returnList.AllocatedMemory.Add(nativeListInternal); for (int i = 0; i < list.Count; i++) { Marshal.WriteIntPtr(nativeListInternal, i * intSize, list[i]); } hb_list_s nativeListStruct = new hb_list_s(); nativeListStruct.items = nativeListInternal; nativeListStruct.items_alloc = list.Count; nativeListStruct.items_count = list.Count; IntPtr nativeListStructPtr = Marshal.AllocHGlobal(Marshal.SizeOf(typeof(hb_list_s))); Marshal.StructureToPtr(nativeListStruct, nativeListStructPtr, false); returnList.ListPtr = nativeListStructPtr; return returnList; } /// /// Creates a native HandBrake list from the given managed list of structures. /// /// The type of structures in the list. /// The managed list to convert. /// The converted native list. public static NativeList ConvertListBack(List list) { NativeList returnList = new NativeList(); int intSize = Marshal.SizeOf(typeof(IntPtr)); IntPtr nativeListInternal = Marshal.AllocHGlobal(list.Count * intSize); returnList.AllocatedMemory.Add(nativeListInternal); for (int i = 0; i < list.Count; i++) { IntPtr itemPtr = Marshal.AllocHGlobal(Marshal.SizeOf(typeof(T))); returnList.AllocatedMemory.Add(itemPtr); Marshal.StructureToPtr(list[i], itemPtr, false); Marshal.WriteIntPtr(nativeListInternal, i * intSize, itemPtr); } hb_list_s nativeListStruct = new hb_list_s(); nativeListStruct.items = nativeListInternal; nativeListStruct.items_alloc = list.Count; nativeListStruct.items_count = list.Count; IntPtr nativeListStructPtr = Marshal.AllocHGlobal(Marshal.SizeOf(typeof(hb_list_s))); Marshal.StructureToPtr(nativeListStruct, nativeListStructPtr, false); returnList.ListPtr = nativeListStructPtr; return returnList; } /// /// Frees all the memory locations in the given list. /// /// The list of memory locations to free. public static void FreeMemory(List memoryList) { foreach (IntPtr memoryLocation in memoryList) { Marshal.FreeHGlobal(memoryLocation); } } } }