private Type MockValueTypeFull( LayoutKind layoutKind = LayoutKind.Sequential, int pack = 0, int size = 0, params Mock <FieldInfo>[] fieldMocks) { var typeMock = new Mock <Type>(); typeMock.CallBase = true; var structLayoutAttribute = new StructLayoutAttribute(layoutKind) { Pack = pack, Size = size, }; var fieldInfos = fieldMocks.Select( m => { m.Setup(f => f.DeclaringType).Returns(typeMock.Object); return(m.Object); }).ToArray(); typeMock.Setup(t => t.BaseType).Returns(typeof(ValueType)); typeMock.Setup(t => t.StructLayoutAttribute).Returns(structLayoutAttribute); typeMock.Setup( t => t.GetFields( BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Instance)) .Returns(fieldInfos); return(typeMock.Object); }
public static void Test_Interface() { // Interafces return null for this property. Type t = typeof(IInterface).Project(); StructLayoutAttribute s = t.StructLayoutAttribute; Assert.Null(s); }
public static void Test_GenericParameter() { // GenericParameter types always return null for this property. Type t = typeof(GenericParameterHolder <>).Project().GetTypeInfo().GenericTypeParameters[0]; StructLayoutAttribute s = t.StructLayoutAttribute; Assert.Null(s); }
public static void Test_Array() { // HasElement types always return null for this property. Type t = typeof(SequentialAnsiEightZero[]).Project(); StructLayoutAttribute s = t.StructLayoutAttribute; Assert.Null(s); }
public void FieldsTest() { var a = new StructLayoutAttribute(LayoutKind.Explicit); Assert.AreEqual((CharSet)0, a.CharSet); Assert.AreEqual(0, a.Pack); Assert.AreEqual(0, a.Size); }
public void CtorTest() { var a = new StructLayoutAttribute(LayoutKind.Explicit); Assert.AreEqual(LayoutKind.Explicit, a.Value); a = new StructLayoutAttribute(LayoutKind.Auto); Assert.AreEqual(LayoutKind.Auto, a.Value); }
/// <summary> /// Marshal a managed object to an unmanaged chunk of memory. If <paramref name="structure"/> is not CustomMarshalable this /// function is the same as <see cref="Marshal.StructureToPtr"/>. /// </summary> /// <param name="structure">A managed object to marshal to unmanaged memory.</param> /// <param name="ptr">Pointer to unmanaged memory. This must be allocated before call</param> /// <param name="fDeleteOld">Indicates whether to delete old memory first</param> public static void StructureToPtr(object structure, IntPtr ptr, bool fDeleteOld) { if (!IsCustomMarshalObject(structure)) { Marshal.StructureToPtr(structure, ptr, fDeleteOld); return; } // first check that the struct has the struct layout attribute StructLayoutAttribute sla = structure.GetType().StructLayoutAttribute; if (sla.IsDefaultAttribute() || sla.Value == LayoutKind.Auto) { throw new ArgumentException("Structure must have StructLayoutAttribute with LayoutKind Explicit or Sequential", "structure"); } // iterate through all struct fields, handling customs, and using Marshal.StructToPtr for others uint extraDataOffset = 0; uint structBase = (uint)ptr.ToInt32(); uint structSize = (uint)Marshal.SizeOf(structure); foreach (FieldInfo field in structure.GetType().GetFields(BindingFlags.NonPublic | BindingFlags.Public | BindingFlags.Instance)) { uint fieldLoc = structBase + (uint)Marshal.OffsetOf(structure.GetType(), field.Name); if (field.IsDefined(typeof(CustomMarshalAsAttribute), true)) { byte[] bytes; CustomMarshalAsAttribute attr = (CustomMarshalAsAttribute)(field.GetCustomAttributes(typeof(CustomMarshalAsAttribute), true)[0]); switch (attr.Value) { case CustomUnmanagedType.LPStr: string val = (string)field.GetValue(structure) + '\0'; bytes = Encoding.ASCII.GetBytes(val); break; case CustomUnmanagedType.LPWStr: val = (string)field.GetValue(structure) + '\0'; bytes = Encoding.Unicode.GetBytes(val); break; default: throw new NotSupportedException("Operation not yet supported"); } uint dataLoc = structBase + structSize + extraDataOffset; Marshal.WriteIntPtr(new IntPtr(fieldLoc), new IntPtr(dataLoc)); // write the raw bytes to dataLoc for (int i = 0; i < bytes.Length; i++, extraDataOffset++) { Marshal.WriteByte(new IntPtr(dataLoc + (uint)i), bytes[i]); } } else { Marshal.StructureToPtr(field.GetValue(structure), new IntPtr(fieldLoc), fDeleteOld); } } }
public static void Test_ExplicitAutoEightFortyTwo() { Type t = typeof(ExplicitAutoEightFortyTwo).Project(); StructLayoutAttribute s = t.StructLayoutAttribute; Assert.Equal(LayoutKind.Explicit, s.Value); Assert.Equal(CharSet.Auto, s.CharSet); Assert.Equal(8, s.Pack); Assert.Equal(42, s.Size); }
public static void Test_UndecoratedClass() { Type t = typeof(UndecoratedClass).Project(); StructLayoutAttribute s = t.StructLayoutAttribute; Assert.Equal(LayoutKind.Auto, s.Value); Assert.Equal(CharSet.Ansi, s.CharSet); Assert.Equal(8, s.Pack); Assert.Equal(0, s.Size); }
public static void Test_SequentialAutoTwoZero() { Type t = typeof(SequentialAutoTwoZero).Project(); StructLayoutAttribute s = t.StructLayoutAttribute; Assert.Equal(LayoutKind.Sequential, s.Value); Assert.Equal(CharSet.Auto, s.CharSet); Assert.Equal(2, s.Pack); Assert.Equal(0, s.Size); }
/// <summary> /// Returns the size defined in the type's metadata. /// </summary> /// <param name="t">The type.</param> /// <returns>The defined size.</returns> public static int DefinedSizeOf(Type t) { StructLayoutAttribute attr = t.StructLayoutAttribute; if (attr == null) { throw new ArgumentException("Type does not have StructLayoutAttribute attribute.", "t"); } return(attr.Size); }
public static void Test_ExplicitAnsiEightZero() { Type t = typeof(ExplicitAnsiEightZero).Project(); StructLayoutAttribute s = t.StructLayoutAttribute; Assert.Equal(LayoutKind.Explicit, s.Value); Assert.Equal(CharSet.Ansi, s.CharSet); Assert.Equal(8, s.Pack); Assert.Equal(0, s.Size); }
public static void TestSequentialAutoZeroZero() { Type t = typeof(SequentialAutoZeroZero).Project(); StructLayoutAttribute s = t.StructLayoutAttribute; Assert.Equal(LayoutKind.Sequential, s.Value); Assert.Equal(CharSet.Auto, s.CharSet); Assert.Equal(8, s.Pack); // Not an error: Pack=0 is treated as if it were Pack=8. Assert.Equal(0, s.Size); }
public static void Test_Derived() { // Though the layout engine honors StructLayout attributes on base classes, Type.StructLayoutAttribute does not. It only looks at the immediate class. Type t = typeof(Derived).Project(); StructLayoutAttribute s = t.StructLayoutAttribute; Assert.Equal(LayoutKind.Auto, s.Value); Assert.Equal(CharSet.Ansi, s.CharSet); Assert.Equal(8, s.Pack); Assert.Equal(0, s.Size); }
public static void Test_Generic() { // Type.StructLayoutAttribute treats generic instance classes as if they were the generic type definition. (The runtime layout engine, on the other hand // generally doesn't allow these.) Type t = typeof(Generic <int>).Project(); StructLayoutAttribute s = t.StructLayoutAttribute; Assert.Equal(LayoutKind.Sequential, s.Value); Assert.Equal(CharSet.Auto, s.CharSet); Assert.Equal(4, s.Pack); Assert.Equal(40, s.Size); }
private void SetStructLayoutPseudoCustomAttribute(CustomAttributeBuilder customBuilder) { object val = customBuilder.GetConstructorArgument(0); LayoutKind layout; if (val is short) { layout = (LayoutKind)(short)val; } else { layout = (LayoutKind)val; } StructLayoutAttribute attr = new StructLayoutAttribute(layout); attr.Pack = (int?)customBuilder.GetFieldValue("Pack") ?? 0; attr.Size = (int?)customBuilder.GetFieldValue("Size") ?? 0; attr.CharSet = customBuilder.GetFieldValue <CharSet>("CharSet") ?? CharSet.None; attribs &= ~TypeAttributes.LayoutMask; switch (attr.Value) { case LayoutKind.Auto: attribs |= TypeAttributes.AutoLayout; break; case LayoutKind.Explicit: attribs |= TypeAttributes.ExplicitLayout; break; case LayoutKind.Sequential: attribs |= TypeAttributes.SequentialLayout; break; } attribs &= ~TypeAttributes.StringFormatMask; switch (attr.CharSet) { case CharSet.None: case CharSet.Ansi: attribs |= TypeAttributes.AnsiClass; break; case CharSet.Auto: attribs |= TypeAttributes.AutoClass; break; case CharSet.Unicode: attribs |= TypeAttributes.UnicodeClass; break; } pack = (short)attr.Pack; size = attr.Size; hasLayout = pack != 0 || size != 0; }
StructLayoutAttribute GetStructLayoutAttribute() { LayoutKind kind; if (IsLayoutSequential) { kind = LayoutKind.Sequential; } else if (IsExplicitLayout) { kind = LayoutKind.Explicit; } else { kind = LayoutKind.Auto; } StructLayoutAttribute attr = new StructLayoutAttribute(kind); if (IsUnicodeClass) { attr.CharSet = CharSet.Unicode; } else if (IsAnsiClass) { attr.CharSet = CharSet.Ansi; } else { attr.CharSet = CharSet.Auto; } if (kind != LayoutKind.Auto) { int packing; GetPacking(out packing, out attr.Size); // 0 means no data provided, we end up with default value if (packing != 0) { attr.Pack = packing; } } return(attr); }
public bool PosTest2() { bool retVal = true; TestLibrary.TestFramework.BeginScenario("PosTest2: Return the field Pack value in StructLayoutAttribute class 2"); try { LayoutKind mylayoutkind = LayoutKind.Sequential; StructLayoutAttribute myInstance = new StructLayoutAttribute(mylayoutkind); if (myInstance.Pack != 0) { TestLibrary.TestFramework.LogError("003", "the ExpectResult is 0 but the ActualResult is " + myInstance.Pack.ToString()); retVal = false; } } catch (Exception e) { TestLibrary.TestFramework.LogError("004", "Unexpect exception:" + e); retVal = false; } return retVal; }
public bool PosTest1() { bool retVal = true; TestLibrary.TestFramework.BeginScenario("PosTest1: Return the Value property in StructLayoutAttribute class 1"); try { LayoutKind mylayoutkind = LayoutKind.Auto; StructLayoutAttribute myInstance = new StructLayoutAttribute(mylayoutkind); if (myInstance.Value != mylayoutkind) { TestLibrary.TestFramework.LogError("001", "the ExpectResult is " + mylayoutkind.ToString() +" but the ActualResult is " + myInstance.Value.ToString()); retVal = false; } } catch (Exception e) { TestLibrary.TestFramework.LogError("002", "Unexpect exception:" + e); retVal = false; } return retVal; }
public bool PosTest1() { bool retVal = true; TestLibrary.TestFramework.BeginScenario("PosTest1: Initialize a instance of StructLayoutAttribute class"); try { LayoutKind mylayoutkind = LayoutKind.Auto; StructLayoutAttribute myInstance = new StructLayoutAttribute(mylayoutkind); if (myInstance == null || myInstance.Value != mylayoutkind) { TestLibrary.TestFramework.LogError("001", "the instance of StructLayoutAttribute creating failed"); retVal = false; } } catch (Exception e) { TestLibrary.TestFramework.LogError("002", "Unexpect exception:" + e); retVal = false; } return retVal; }
public bool PosTest2() { bool retVal = true; TestLibrary.TestFramework.BeginScenario("PosTest2: Return the field Size value in StructLayoutAttribute class 2"); try { LayoutKind mylayoutkind = LayoutKind.Sequential; StructLayoutAttribute myInstance = new StructLayoutAttribute(mylayoutkind); if (myInstance.Size != 0) { TestLibrary.TestFramework.LogError("003", "the ExpectResult is 0 but the ActualResult is " + myInstance.Size.ToString()); retVal = false; } } catch (Exception e) { TestLibrary.TestFramework.LogError("004", "Unexpect exception:" + e); retVal = false; } return(retVal); }
public bool PosTest1() { bool retVal = true; TestLibrary.TestFramework.BeginScenario("PosTest1: Return the field Pack value in StructLayoutAttribute class 1"); try { LayoutKind mylayoutkind = LayoutKind.Auto; StructLayoutAttribute myInstance = new StructLayoutAttribute(mylayoutkind); if (myInstance.Pack != 0) { TestLibrary.TestFramework.LogError("001", "the ExpectResult is 0 but the ActualResult is " + myInstance.Pack.ToString()); retVal = false; } } catch (Exception e) { TestLibrary.TestFramework.LogError("002", "Unexpect exception:" + e); retVal = false; } return(retVal); }
public bool PosTest1() { bool retVal = true; TestLibrary.TestFramework.BeginScenario("PosTest1: Initialize a instance of StructLayoutAttribute class"); try { LayoutKind mylayoutkind = LayoutKind.Auto; StructLayoutAttribute myInstance = new StructLayoutAttribute(mylayoutkind); if (myInstance == null || myInstance.Value != mylayoutkind) { TestLibrary.TestFramework.LogError("001", "the instance of StructLayoutAttribute creating failed"); retVal = false; } } catch (Exception e) { TestLibrary.TestFramework.LogError("002", "Unexpect exception:" + e); retVal = false; } return(retVal); }
public virtual byte[] GetRvaField() { uint num; uint num1; if ((this.Attributes & FieldAttributes.HasFieldRVA) == FieldAttributes.PrivateScope) { throw new InvalidOperationException(MetadataStringTable.OperationValidOnRVAFieldsOnly); } StructLayoutAttribute structLayoutAttribute = this.FieldType.StructLayoutAttribute; if (structLayoutAttribute.Value == LayoutKind.Auto) { throw new InvalidOperationException(MetadataStringTable.OperationInvalidOnAutoLayoutFields); } this.m_resolver.RawImport.GetRVA(this.MetadataToken, out num, out num1); int size = structLayoutAttribute.Size; if (size == 0) { switch (Type.GetTypeCode(this.FieldType)) { case TypeCode.Int32: { size = 4; break; } case TypeCode.Int64: { size = 8; break; } } } return(this.m_resolver.RawMetadata.ReadRva((long)num, size)); }
void Read(ref object o, bool isLittleEndian) { BinaryReader m_stream = (BinaryReader)this.m_stream; Type t = o.GetType(); StructLayoutAttribute structlayout = t.StructLayoutAttribute; EndianBitConverter b; if (!isLittleEndian) { b = new BigEndianBitConverter(); } else { b = new LittleEndianBitConverter(); } if (t == typeof(int)) { o = b.ToInt32(m_stream.ReadBytes(4), 0); } else if (t.IsEnum) { o = b.ToInt32(m_stream.ReadBytes(4), 0); } else if (t == typeof(uint)) { o = b.ToUInt32(m_stream.ReadBytes(4), 0); } else if (t == typeof(short)) { o = b.ToInt16(m_stream.ReadBytes(2), 0); } else if (t == typeof(ushort)) { o = b.ToUInt16(m_stream.ReadBytes(2), 0); } else if (t == typeof(byte)) { o = m_stream.ReadBytes(1)[0]; } else if (t == typeof(long)) { o = b.ToInt64(m_stream.ReadBytes(8), 0); } else if (t == typeof(ulong)) { o = b.ToUInt64(m_stream.ReadBytes(8), 0); } else if (t == typeof(float)) { o = b.ToSingle(m_stream.ReadBytes(4), 0); } else if (t == typeof(double)) { o = b.ToDouble(m_stream.ReadBytes(8), 0); } else if (t.IsArray) { if (t.GetElementType() == typeof(byte)) { byte[] arr = (byte[])o; m_stream.Read(arr, 0, arr.Length); } else { ReadIntoArray(o, isLittleEndian); } } else if (structlayout != null) { ReadIntoStruct(o, m_stream); } else { throw new Exception("I don't know how to write this object:" + o.GetType().Name + " Please include the [StructLayout] attribute"); } }
void Write(object o, bool isLittleEndian, int arraysize) { BinaryWriter m_stream = (BinaryWriter)this.m_stream; StructLayoutAttribute structlayout = o.GetType().StructLayoutAttribute; EndianBitConverter b; if (!isLittleEndian) { b = new BigEndianBitConverter(); } else { b = new LittleEndianBitConverter(); } if (o.GetType() == typeof(int)) { m_stream.Write(b.GetBytes((int)o)); } else if (o.GetType() == typeof(uint)) { m_stream.Write(b.GetBytes((uint)o)); } else if (o.GetType() == typeof(short)) { m_stream.Write(b.GetBytes((short)o)); } else if (o.GetType() == typeof(ushort)) { m_stream.Write(b.GetBytes((ushort)o)); } else if (o.GetType() == typeof(long)) { m_stream.Write(b.GetBytes((long)o)); } else if (o.GetType() == typeof(ulong)) { m_stream.Write(b.GetBytes((ulong)o)); } else if (o.GetType() == typeof(float)) { m_stream.Write(b.GetBytes((float)o)); } else if (o.GetType() == typeof(double)) { m_stream.Write(b.GetBytes((double)o)); } else if (o.GetType().IsEnum) { m_stream.Write(b.GetBytes((int)o)); } else if (o.GetType() == typeof(byte)) { m_stream.Write((byte)o); } else if (o.GetType().IsArray) { Array arr = (Array)o; for (int i = 0; i < arraysize; i++) { Write(arr.GetValue(i), isLittleEndian, 0); } } else if (structlayout != null) { Type objecttype = o.GetType(); FieldInfo[] fis = objecttype.GetFields(); // Sort the fields into the order they were specified Dictionary <string, IntPtr> fieldorder = new Dictionary <string, IntPtr>(); foreach (FieldInfo fi in fis) { fieldorder[fi.Name] = Marshal.OffsetOf(objecttype, fi.Name); } Array.Sort(fis, (x, y) => fieldorder[x.Name].ToInt32() - fieldorder[y.Name].ToInt32()); List <object> towrite = new List <object>(); foreach (FieldInfo fi in fis) { object[] lil = fi.GetCustomAttributes(typeof(LittleEndianAttribute), false); object[] big = fi.GetCustomAttributes(typeof(BigEndianAttribute), false); object[] array = fi.GetCustomAttributes(typeof(ArraySizeAttribute), false); InternalUseAttribute[] internalUse = (InternalUseAttribute[])fi.GetCustomAttributes(typeof(InternalUseAttribute), false); if (internalUse.Length > 0) { continue; } bool littleendian = big.Length == 0; object field = fi.GetValue(o); if (array.Length > 0 && fi.FieldType.IsArray) { ArraySizeAttribute arr = (ArraySizeAttribute)array[0]; int size = FormattedReader.GetArraySize(o, objecttype, arr); if (field == null) { field = Array.CreateInstance(fi.FieldType.GetElementType(), size); } Write(field, littleendian, size); } else if (fi.FieldType.IsEnum) { Write((int)field, littleendian, 0); } else { Write(field, littleendian, 0); } } } else { throw new Exception("I don't know how to write this object:" + o.GetType().Name + " Please include the [StructLayout] attribute"); } }
private static MemberInfo[] GetStructFormat(Type t) { if (false) { lock (FunctorToLayout) { PrologTermLayout layout; if (TypeToLayout.TryGetValue(t, out layout)) { return(layout.FieldInfos); } } } bool specialXMLType = false; if (!t.IsEnum) { var ta = t.GetCustomAttributes(typeof(XmlTypeAttribute), false); if (ta != null && ta.Length > 0) { XmlTypeAttribute xta = (XmlTypeAttribute)ta[0]; specialXMLType = true; } } MemberInfo[] tGetFields = null; if (specialXMLType) { List <MemberInfo> fis = new List <MemberInfo>(); foreach (var e in t.GetFields(InstanceFields)) { var use = e.GetCustomAttributes(typeof(XmlArrayItemAttribute), false); if (use == null || use.Length < 1) { continue; } fis.Add(e); } foreach (var e in t.GetProperties(InstanceFields)) { var use = e.GetCustomAttributes(typeof(XmlArrayItemAttribute), false); if (use == null || use.Length < 1) { continue; } fis.Add(e); } tGetFields = fis.ToArray(); } else { // look for [StructLayout(LayoutKind.Sequential)] var ta = t.GetCustomAttributes(typeof(StructLayoutAttribute), false); if (ta != null && ta.Length > 0) { StructLayoutAttribute xta = (StructLayoutAttribute)ta[0]; // ReSharper disable ConditionIsAlwaysTrueOrFalse if (xta.Value == LayoutKind.Sequential || true /* all sequential layouts*/) // ReSharper restore ConditionIsAlwaysTrueOrFalse { tGetFields = t.GetFields(InstanceFields); } } if (tGetFields == null) { tGetFields = t.GetFields(InstanceFields); } } if (tGetFields.Length == 0) { Warn("No fields in {0}", t); } return(tGetFields); }
public static void ValidateAttribute(StructLayoutAttribute atrib, LayoutKind kind, CharSet charset, int pack) { Assert.Equal(atrib.Value, kind); Assert.Equal(atrib.CharSet, charset); Assert.Equal(atrib.Pack, pack); }
/// <summary> /// Marshal an unmanaged to pointer to a managed object. If <paramref name="structureType"/> is not CustomMarshalable, this /// function is the same as <see cref="Marshal.StructureToPtr"/>. /// </summary> /// <param name="ptr">Pointer to unmanaged memory</param> /// <param name="structureType">Type of managed object to instantiate</param> /// <returns>Managed instance of <paramref name="structureType"/> type</returns> public static object PtrToStructure(IntPtr ptr, Type structureType) { if (ptr == IntPtr.Zero) { return(null); } if (structureType == null) { throw new ArgumentNullException("structureType"); } if (structureType.IsGenericType) { throw new ArgumentException("Structure type must be non-generic", "structureType"); } if (!IsCustomMarshalType(structureType)) { return(Marshal.PtrToStructure(ptr, structureType)); } StructLayoutAttribute sla = structureType.StructLayoutAttribute; if (sla.IsDefaultAttribute() || sla.Value == LayoutKind.Auto) { throw new ArgumentException("Structure must have StructLayoutAttribute with LayoutKind Explicit or Sequential", "structure"); } object structure = Activator.CreateInstance(structureType); uint structBase = (uint)ptr.ToInt32(); uint structSize = (uint)Marshal.SizeOf(structure); foreach (FieldInfo field in structureType.GetFields(BindingFlags.NonPublic | BindingFlags.Public | BindingFlags.Instance)) { uint fieldLoc = structBase + (uint)Marshal.OffsetOf(structureType, field.Name); if (field.IsDefined(typeof(CustomMarshalAsAttribute), true)) { IntPtr extraDataLoc = Marshal.ReadIntPtr(new IntPtr(fieldLoc)); CustomMarshalAsAttribute attr = (CustomMarshalAsAttribute)(field.GetCustomAttributes(typeof(CustomMarshalAsAttribute), true)[0]); switch (attr.Value) { case CustomUnmanagedType.LPStr: field.SetValue(structure, Marshal.PtrToStringAnsi(extraDataLoc)); break; case CustomUnmanagedType.LPWStr: field.SetValue(structure, Marshal.PtrToStringUni(extraDataLoc)); break; default: throw new NotSupportedException("Operation not currently supported"); } } else { field.SetValue(structure, Marshal.PtrToStructure(new IntPtr(fieldLoc), field.FieldType)); } } return(structure); }
public void Ctor_LayoutKind(LayoutKind layoutKind) { var attribute = new StructLayoutAttribute(layoutKind); Assert.Equal(layoutKind, attribute.Value); }
public void Ctor_ShortLayoutKind(short layoutKind) { var attribute = new StructLayoutAttribute(layoutKind); Assert.Equal((LayoutKind)layoutKind, attribute.Value); }
private static void DisplayLayoutAttribute(StructLayoutAttribute sla) { Console.WriteLine("\r\nCharSet: " + sla.CharSet.ToString() + "\r\n Pack: " + sla.Pack.ToString() + "\r\n Size: " + sla.Size.ToString() + "\r\n Value: " + sla.Value.ToString()); }