public void Test() { int valType = 0xFF; Assert.That(new IntPtr(&valType), Is.EqualTo(Unsafe.AddressOf(ref valType))); string s = "foo"; Assert.That(new IntPtr(CSUnsafe.AsPointer(ref s)), Is.EqualTo(Unsafe.AddressOf(ref s))); IntPtr sChars = Unsafe.AddressOfHeap(ref s, OffsetType.StringData); Assert.That(Marshal.ReadInt16(sChars), Is.EqualTo(s[0])); int[] arr = { 1, 2, 3 }; IntPtr arrData = Unsafe.AddressOfHeap(ref arr, OffsetType.ArrayData); Assert.That(Marshal.ReadInt32(arrData), Is.EqualTo(arr[0])); Dummy d = new Dummy(100, "bar"); IntPtr dData = Unsafe.AddressOfHeap(ref d, OffsetType.Fields); // Largest field is first in memory Assert.That(Marshal.ReadInt32(dData, IntPtr.Size), Is.EqualTo(100)); }
public static T SafeRead <T>(Pointer <T> ptr, int elemOfs = 0) { T t = default; IntPtr addr = PointerUtils.Offset <T>(ptr.Address, elemOfs); if (Assertion.Throws <NullReferenceException>(delegate { t = CSUnsafe.Read <T>(addr.ToPointer()); })) { return(default);
public static void Swap <T>(void *a, void *b) { T aval = CSUnsafe.Read <T>(a); T bval = CSUnsafe.Read <T>(b); CSUnsafe.Write(a, bval); CSUnsafe.Write(b, aval); }
public static string Create <T>(IntPtr p, int len, ToStringOptions options = ToStringOptions.ZeroPadHex) { byte[] mem = Memory.ReadBytes(p, 0, len); int possibleTypes = mem.Length / Unsafe.SizeOf <T>(); if (typeof(T) == typeof(byte)) { return(Collections.ToString(mem, options)); } string As(int ofs) { if (possibleTypes < 1) { throw new Exception($"Insufficient memory for type {typeof(T).Name}"); } var alloc = Marshal.AllocHGlobal(mem.Length); Memory.Write(alloc, mem); IntPtr adj = alloc + ofs * Unsafe.SizeOf <T>(); string s; if (options.HasFlag(ToStringOptions.Hex)) { s = Hex.TryCreateHex(CSUnsafe.Read <T>(adj.ToPointer())); } else { s = CSUnsafe.Read <T>(adj.ToPointer()).ToString(); } Marshal.FreeHGlobal(alloc); return(s); } string[] @out = new string[possibleTypes]; for (int i = 0; i < possibleTypes; i++) { @out[i] = As(i); } return(Collections.ToString(@out, options | ~ToStringOptions.UseCommas)); }
public static int SizeOf <T>() { return(CSUnsafe.SizeOf <T>()); }
public void SizeOf_Test() { // Inline Unsafe.SizeOf<T> CSUnsafe.SizeOf <int>(); }