public void WriteAndReadDouble() { // Arrange const double originalValue = 3.141592; LocalUnmanagedMemory local; double ret; // Act using (local = new LocalUnmanagedMemory(MarshalType<double>.Size)) { local.Write(originalValue); ret = local.Read<double>(); } // Assert Assert.AreEqual(originalValue, ret, "Both values aren't equal."); Assert.AreEqual(IntPtr.Zero, local.Address); }
public void WriteAndReadCustomStruct() { // Arrange var customStruct = Resources.CustomStruct; LocalUnmanagedMemory local; Point ret; // Act using (local = new LocalUnmanagedMemory(MarshalType <Point> .Size)) { local.Write(customStruct); ret = local.Read <Point>(); } // Assert Assert.AreEqual(customStruct, ret, "Both structures aren't equal."); Assert.AreEqual(IntPtr.Zero, local.Address); }
public void WriteAndReadCustomStruct() { // Arrange var customStruct = Resources.CustomStruct; LocalUnmanagedMemory local; Point ret; // Act using (local = new LocalUnmanagedMemory(MarshalType<Point>.Size)) { local.Write(customStruct); ret = local.Read<Point>(); } // Assert Assert.AreEqual(customStruct, ret, "Both structures aren't equal."); Assert.AreEqual(IntPtr.Zero, local.Address); }
public void WriteAndReadDouble() { // Arrange const double originalValue = 3.141592; LocalUnmanagedMemory local; double ret; // Act using (local = new LocalUnmanagedMemory(MarshalType <double> .Size)) { local.Write(originalValue); ret = local.Read <double>(); } // Assert Assert.AreEqual(originalValue, ret, "Both values aren't equal."); Assert.AreEqual(IntPtr.Zero, local.Address); }
/// <summary> /// Marshals an array of byte to a managed object. /// </summary> /// <param name="byteArray">The array of bytes corresponding to a managed object.</param> /// <param name="index">[Optional] Where to start the conversion of bytes to the managed object.</param> /// <returns>A managed object.</returns> public static T ByteArrayToObject(byte[] byteArray, int index = 0) { // We'll tried to avoid marshalling as it really slows the process // First, check if the type can be converted without marshalling switch (TypeCode) { case TypeCode.Object: if (IsIntPtr) { switch (byteArray.Length) { case 1: return((T)(object)new IntPtr(BitConverter.ToInt32(new byte[] { byteArray[index], 0x0, 0x0, 0x0 }, index))); case 2: return((T)(object)new IntPtr(BitConverter.ToInt32(new byte[] { byteArray[index], byteArray[index + 1], 0x0, 0x0 }, index))); case 4: return((T)(object)new IntPtr(BitConverter.ToInt32(byteArray, index))); case 8: return((T)(object)new IntPtr(BitConverter.ToInt64(byteArray, index))); } } break; case TypeCode.Boolean: return((T)(object)BitConverter.ToBoolean(byteArray, index)); case TypeCode.Byte: return((T)(object)byteArray[index]); case TypeCode.Char: return((T)(object)Encoding.UTF8.GetChars(byteArray)[index]); case TypeCode.Double: return((T)(object)BitConverter.ToDouble(byteArray, index)); case TypeCode.Int16: return((T)(object)BitConverter.ToInt16(byteArray, index)); case TypeCode.Int32: return((T)(object)BitConverter.ToInt32(byteArray, index)); case TypeCode.Int64: return((T)(object)BitConverter.ToInt64(byteArray, index)); case TypeCode.Single: return((T)(object)BitConverter.ToSingle(byteArray, index)); case TypeCode.String: throw new InvalidCastException("This method doesn't support string conversion."); case TypeCode.UInt16: return((T)(object)BitConverter.ToUInt16(byteArray, index)); case TypeCode.UInt32: return((T)(object)BitConverter.ToUInt32(byteArray, index)); case TypeCode.UInt64: return((T)(object)BitConverter.ToUInt64(byteArray, index)); } // Allocate a block of unmanaged memory using (var unmanaged = new LocalUnmanagedMemory(Size)) { // Write the array of bytes inside the unmanaged memory unmanaged.Write(byteArray, index); // Return a managed object created from the block of unmanaged memory return(unmanaged.Read <T>()); } }
/// <summary> /// Marshals a managed object to an array of bytes. /// </summary> /// <param name="obj">The object to marshal.</param> /// <returns>A array of bytes corresponding to the managed object.</returns> public static byte[] ObjectToByteArray(T obj) { // We'll tried to avoid marshalling as it really slows the process // First, check if the type can be converted without marhsalling switch (TypeCode) { case TypeCode.Object: if (IsIntPtr) { switch (Size) { case 4: return(BitConverter.GetBytes(((IntPtr)(object)obj).ToInt32())); case 8: return(BitConverter.GetBytes(((IntPtr)(object)obj).ToInt64())); } } break; case TypeCode.Boolean: return(BitConverter.GetBytes((bool)(object)obj)); case TypeCode.Char: return(Encoding.UTF8.GetBytes(new[] { (char)(object)obj })); case TypeCode.Double: return(BitConverter.GetBytes((double)(object)obj)); case TypeCode.Int16: return(BitConverter.GetBytes((short)(object)obj)); case TypeCode.Int32: return(BitConverter.GetBytes((int)(object)obj)); case TypeCode.Int64: return(BitConverter.GetBytes((long)(object)obj)); case TypeCode.Single: return(BitConverter.GetBytes((float)(object)obj)); case TypeCode.String: throw new InvalidCastException("This method doesn't support string conversion."); case TypeCode.UInt16: return(BitConverter.GetBytes((ushort)(object)obj)); case TypeCode.UInt32: return(BitConverter.GetBytes((uint)(object)obj)); case TypeCode.UInt64: return(BitConverter.GetBytes((ulong)(object)obj)); } // Check if it's not a common type // Allocate a block of unmanaged memory using (var unmanaged = new LocalUnmanagedMemory(Size)) { // Write the object inside the unmanaged memory unmanaged.Write(obj); // Return the content of the block of unmanaged memory return(unmanaged.Read()); } }
/// <summary> /// Marshals an array of byte to a managed object. /// </summary> /// <param name="byteArray">The array of bytes corresponding to a managed object.</param> /// <returns>A managed object.</returns> public unsafe static T ByteArrayToObject(byte[] byteArray) { var requiresMarshal = MarshalCache <T> .TypeRequiresMarshal; var size = requiresMarshal ? MarshalCache <T> .Size : Unsafe.SizeOf <T>(); fixed(byte *b = byteArray) { if (requiresMarshal) { return(Marshal.PtrToStructure <T>(new IntPtr(b))); } return(Unsafe.Read <T>(b)); } #if false // We'll tried to avoid marshalling as it really slows the process // First, check if the type can be converted without marhsalling switch (TypeCode) { case TypeCode.Object: if (IsIntPtr) { switch (byteArray.Length) { case 1: return ((T) (object) new IntPtr(BitConverter.ToInt32(new byte[] { byteArray[0], 0x0, 0x0, 0x0 }, 0))); case 2: return ((T) (object) new IntPtr( BitConverter.ToInt32(new byte[] { byteArray[0], byteArray[1], 0x0, 0x0 }, 0))); case 4: return((T)(object)new IntPtr(BitConverter.ToInt32(byteArray, 0))); case 8: return((T)(object)new IntPtr(BitConverter.ToInt64(byteArray, 0))); } } break; case TypeCode.Boolean: return((T)(object)BitConverter.ToBoolean(byteArray, 0)); case TypeCode.Byte: return((T)(object)byteArray[0]); case TypeCode.Char: return((T)(object)Encoding.UTF8.GetChars(byteArray)[0]); //BitConverter.ToChar(byteArray, 0); case TypeCode.Double: return((T)(object)BitConverter.ToDouble(byteArray, 0)); case TypeCode.Int16: return((T)(object)BitConverter.ToInt16(byteArray, 0)); case TypeCode.Int32: return((T)(object)BitConverter.ToInt32(byteArray, 0)); case TypeCode.Int64: return((T)(object)BitConverter.ToInt64(byteArray, 0)); case TypeCode.Single: return((T)(object)BitConverter.ToSingle(byteArray, 0)); case TypeCode.String: throw new InvalidCastException("This method doesn't support string conversion."); case TypeCode.UInt16: return((T)(object)BitConverter.ToUInt16(byteArray, 0)); case TypeCode.UInt32: return((T)(object)BitConverter.ToUInt32(byteArray, 0)); case TypeCode.UInt64: return((T)(object)BitConverter.ToUInt64(byteArray, 0)); } // Check if it's not a common type // Allocate a block of unmanaged memory using (var unmanaged = new LocalUnmanagedMemory(Size)) { // Write the array of bytes inside the unmanaged memory unmanaged.Write(byteArray); // Return a managed object created from the block of unmanaged memory return(unmanaged.Read <T>()); } #endif }
/// <summary> /// Marshals an array of byte to a managed object. /// </summary> /// <param name="byteArray">The array of bytes corresponding to a managed object.</param> /// <returns>A managed object.</returns> public static T ByteArrayToObject(byte[] byteArray) { // We'll tried to avoid marshalling as it really slows the process // First, check if the type can be converted without marshalling switch (TypeCode) { case TypeCode.Object: if (IsIntPtr) { switch (byteArray.Length) { case 1: return ((T) (object) new IntPtr(BitConverter.ToInt32(new byte[] { byteArray[0], 0x0, 0x0, 0x0 }, 0))); case 2: return ((T) (object) new IntPtr( BitConverter.ToInt32(new byte[] { byteArray[0], byteArray[1], 0x0, 0x0 }, 0))); case 4: return((T)(object)new IntPtr(BitConverter.ToInt32(byteArray, 0))); case 8: return((T)(object)new IntPtr(BitConverter.ToInt64(byteArray, 0))); } } break; case TypeCode.Boolean: return((T)(object)BitConverter.ToBoolean(byteArray, 0)); case TypeCode.Byte: return((T)(object)byteArray[0]); case TypeCode.Char: return((T)(object)Encoding.UTF8.GetChars(byteArray)[0]); //BitConverter.ToChar(byteArray, 0); case TypeCode.Double: return((T)(object)BitConverter.ToDouble(byteArray, 0)); case TypeCode.Int16: return((T)(object)BitConverter.ToInt16(byteArray, 0)); case TypeCode.Int32: return((T)(object)BitConverter.ToInt32(byteArray, 0)); case TypeCode.Int64: return((T)(object)BitConverter.ToInt64(byteArray, 0)); case TypeCode.Single: return((T)(object)BitConverter.ToSingle(byteArray, 0)); case TypeCode.String: throw new InvalidCastException("This method doesn't support string conversion."); case TypeCode.UInt16: return((T)(object)BitConverter.ToUInt16(byteArray, 0)); case TypeCode.UInt32: return((T)(object)BitConverter.ToUInt32(byteArray, 0)); case TypeCode.UInt64: return((T)(object)BitConverter.ToUInt64(byteArray, 0)); case TypeCode.Decimal: return((T)(object)BitConverter.ToDouble(byteArray, 0)); case TypeCode.SByte: return((T)(object)BitConverter.ToChar(byteArray, 0)); case TypeCode.DateTime: throw new InvalidCastException( "This method doesn't support DateTime conversion. Use .ToBinary() to store as Int64."); case TypeCode.DBNull: throw new InvalidCastException("This method doesn't support null conversion."); case TypeCode.Empty: throw new InvalidCastException("This method doesn't support empty object conversion."); default: throw new ArgumentOutOfRangeException(); } // Check if it's not a common type // Allocate a block of unmanaged memory using var unmanaged = new LocalUnmanagedMemory(Size); // Write the array of bytes inside the unmanaged memory unmanaged.Write(byteArray); // Return a managed object created from the block of unmanaged memory return(unmanaged.Read <T>()); }