using System.Collections; using System.Collections.Generic; // ReSharper disable once CheckNamespace namespace System.Runtime.InteropServices { internal static class InteropUtil { private const int cbBuffer = 256; public static T ToStructure(IntPtr ptr) => (T)Marshal.PtrToStructure(ptr, typeof(T)); public static IntPtr StructureToPtr(object value) { IntPtr ret = Marshal.AllocHGlobal(Marshal.SizeOf(value)); Marshal.StructureToPtr(value, ret, false); return ret; } public static void AllocString(ref IntPtr ptr, ref uint size) { FreeString(ref ptr, ref size); if (size == 0) size = cbBuffer; ptr = Marshal.AllocHGlobal(cbBuffer); } public static void FreeString(ref IntPtr ptr, ref uint size) { if (ptr != IntPtr.Zero) { Marshal.FreeHGlobal(ptr); ptr = IntPtr.Zero; size = 0; } } public static string GetString(IntPtr pString) => Marshal.PtrToStringUni(pString); public static bool SetString(ref IntPtr ptr, ref uint size, string value = null) { string s = GetString(ptr); if (value == string.Empty) value = null; if (string.CompareOrdinal(s, value) != 0) { FreeString(ref ptr, ref size); if (value != null) { ptr = Marshal.StringToHGlobalUni(value); size = (uint)value.Length + 1; } return true; } return false; } /// /// Converts an that points to a C-style array into a CLI array. /// /// Type of native structure used by the C-style array. /// Output type for the CLI array. must be able to convert to . /// The pointing to the native array. /// The number of items in the native array. /// An array of type containing the converted elements of the native array. public static T[] ToArray(IntPtr ptr, int count) where TS : IConvertible { var ret = new T[count]; var stSize = Marshal.SizeOf(typeof(TS)); for (var i = 0; i < count; i++) { var tempPtr = new IntPtr(ptr.ToInt64() + (i * stSize)); var val = ToStructure(tempPtr); ret[i] = (T)Convert.ChangeType(val, typeof(T)); } return ret; } /// /// Converts an that points to a C-style array into a CLI array. /// /// Type of native structure used by the C-style array. /// The pointing to the native array. /// The number of items in the native array. /// An array of type containing the elements of the native array. public static T[] ToArray(IntPtr ptr, int count) { var ret = new T[count]; var stSize = Marshal.SizeOf(typeof(T)); for (var i = 0; i < count; i++) { var tempPtr = new IntPtr(ptr.ToInt64() + (i * stSize)); ret[i] = ToStructure(tempPtr); } return ret; } } internal class ComEnumerator : IEnumerator where T : class where TIn : class { protected readonly Func converter; protected IEnumerator iEnum; public ComEnumerator(Func getCount, Func indexer, Func converter) { IEnumerator Enumerate() { for (var x = 1; x <= getCount(); x++) yield return indexer(x); } this.converter = converter; iEnum = Enumerate(); } public ComEnumerator(Func getCount, Func indexer, Func converter) { IEnumerator Enumerate() { for (var x = 1; x <= getCount(); x++) yield return indexer(x); } this.converter = converter; iEnum = Enumerate(); } object IEnumerator.Current => Current; public virtual T Current => converter(iEnum?.Current); public virtual void Dispose() { iEnum?.Dispose(); iEnum = null; } public virtual bool MoveNext() => iEnum?.MoveNext() ?? false; public virtual void Reset() { iEnum?.Reset(); } } }