PinnedArray.ps1
Add-Type -TypeDefinition @'
namespace PowerShellUtils { using System; using System.Runtime.InteropServices; public sealed class PinnedArray<T> : IDisposable { private readonly T[] array; private readonly GCHandle gcHandle; public readonly bool ClearOnDispose = true; private bool isDisposed = false; public static implicit operator T[](PinnedArray<T> pinnedArray) { return pinnedArray.Array; } public T this[int key] { get { if (isDisposed) { throw new ObjectDisposedException("PinnedArray"); } return array[key]; } set { if (isDisposed) { throw new ObjectDisposedException("PinnedArray"); } array[key] = value; } } public T[] Array { get { if (isDisposed) { throw new ObjectDisposedException("PinnedArray"); } return array; } } public int Length { get { if (isDisposed) { throw new ObjectDisposedException("PinnedArray"); } return array.Length; } } public int Count { get { return Length; } } public PinnedArray(uint count) { array = new T[count]; gcHandle = GCHandle.Alloc(Array, GCHandleType.Pinned); } public PinnedArray(uint count, bool clearOnDispose) : this(count) { ClearOnDispose = clearOnDispose; } public PinnedArray(T[] array) { if (array == null) { throw new ArgumentNullException("array"); } this.array = array; gcHandle = GCHandle.Alloc(this.array, GCHandleType.Pinned); } public PinnedArray(T[] array, bool clearOnDispose) : this(array) { ClearOnDispose = clearOnDispose; } ~PinnedArray() { Dispose(); } public void Dispose() { if (isDisposed) { return; } if (array != null && ClearOnDispose) { System.Array.Clear(array, 0, array.Length); } if (gcHandle != null) { gcHandle.Free(); } isDisposed = true; } } } '@ |