changeset 76:b05350c24596

Added InteropUtil for safe pinned array and string access
author Ivo Smits <Ivo@UCIS.nl>
date Mon, 03 Feb 2014 22:53:58 +0100
parents 50d4aed66c67
children b5e27116bd2a
files UCIS.Core.csproj Util/InteropUtil.cs
diffstat 2 files changed, 48 insertions(+), 0 deletions(-) [+]
line wrap: on
line diff
--- a/UCIS.Core.csproj	Mon Feb 03 22:53:31 2014 +0100
+++ b/UCIS.Core.csproj	Mon Feb 03 22:53:58 2014 +0100
@@ -176,6 +176,7 @@
     <Compile Include="Util\PrebufferingStream.cs" />
     <Compile Include="Util\QueuedPacketStream.cs" />
     <Compile Include="Util\TapeArchive.cs" />
+    <Compile Include="Util\InteropUtil.cs" />
     <Compile Include="Util\WorkQueue.cs" />
     <Compile Include="VNCServer\IFramebuffer.cs" />
     <Compile Include="VNCServer\VNCServer.cs" />
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/Util/InteropUtil.cs	Mon Feb 03 22:53:58 2014 +0100
@@ -0,0 +1,47 @@
+using System;
+using System.Collections.Generic;
+using System.Text;
+using System.IO;
+using System.Runtime.InteropServices;
+
+namespace UCIS.Util {
+	public class PinnedObject : SafeHandle {
+		GCHandle gch;
+		public PinnedObject(Object obj)
+			: base(IntPtr.Zero, true) {
+			gch = GCHandle.Alloc(obj, GCHandleType.Pinned);
+			SetHandle(gch.AddrOfPinnedObject());
+		}
+		public override bool IsInvalid { get { return handle == IntPtr.Zero; } }
+		protected override bool ReleaseHandle() {
+			if (gch.IsAllocated) {
+				gch.Free();
+				return true;
+			} else {
+				return false;
+			}
+		}
+		public static implicit operator IntPtr(PinnedObject p) { return p.DangerousGetHandle(); }
+		public static implicit operator PinnedObject(Array o) { return new PinnedObject(o); }
+	}
+	public class PinnedString : SafeHandle {
+		public PinnedString(String str, Boolean unicode)
+			: base(IntPtr.Zero, true) {
+			SetHandle(unicode ? Marshal.StringToHGlobalUni(str) : Marshal.StringToHGlobalAnsi(str));
+		}
+		public override bool IsInvalid { get { return handle == IntPtr.Zero; } }
+		protected override bool ReleaseHandle() {
+			Marshal.FreeHGlobal(handle);
+			return true;
+		}
+		public static implicit operator IntPtr(PinnedString p) { return p.DangerousGetHandle(); }
+	}
+	public class PinnedStringAnsi : PinnedString {
+		public PinnedStringAnsi(String str) : base(str, false) { }
+		public static implicit operator PinnedStringAnsi(String s) { return new PinnedStringAnsi(s); }
+	}
+	public class PinnedStringUni : PinnedString {
+		public PinnedStringUni(String str) : base(str, true) { }
+		public static implicit operator PinnedStringUni(String s) { return new PinnedStringUni(s); }
+	}
+}