public void WriteIntPtr_StructWithReferenceTypes_ReturnsExpected() { int pointerOffset = Marshal.OffsetOf <StructWithReferenceTypes>(nameof(StructWithReferenceTypes.pointerValue)).ToInt32(); int stringOffset = Marshal.OffsetOf <StructWithReferenceTypes>(nameof(StructWithReferenceTypes.stringValue)).ToInt32(); int arrayOffset = Marshal.OffsetOf <StructWithReferenceTypes>(nameof(StructWithReferenceTypes.byValueArray)).ToInt32(); object structure = new StructWithReferenceTypes { pointerValue = (IntPtr)100, stringValue = "ABC", byValueArray = new IntPtr[10] { (IntPtr)1, (IntPtr)2, (IntPtr)3, (IntPtr)4, (IntPtr)5, (IntPtr)6, (IntPtr)7, (IntPtr)8, (IntPtr)9, (IntPtr)10 } }; Marshal.WriteIntPtr(structure, pointerOffset, (IntPtr)200); Marshal.WriteIntPtr(structure, arrayOffset + IntPtr.Size * 9, (IntPtr)100); Assert.Equal((IntPtr)200, ((StructWithReferenceTypes)structure).pointerValue); Assert.Equal("ABC", ((StructWithReferenceTypes)structure).stringValue); Assert.Equal(new IntPtr[10] { (IntPtr)1, (IntPtr)2, (IntPtr)3, (IntPtr)4, (IntPtr)5, (IntPtr)6, (IntPtr)7, (IntPtr)8, (IntPtr)9, (IntPtr)100 }, ((StructWithReferenceTypes)structure).byValueArray); Assert.Equal((IntPtr)200, Marshal.ReadIntPtr(structure, pointerOffset)); Assert.NotEqual(IntPtr.Zero, Marshal.ReadIntPtr(structure, stringOffset)); Assert.Equal((IntPtr)100, Marshal.ReadIntPtr(structure, arrayOffset + IntPtr.Size * 9)); }
public void WriteInt32_StructWithReferenceTypes_ReturnsExpected() { int pointerOffset = Marshal.OffsetOf <StructWithReferenceTypes>(nameof(StructWithReferenceTypes.pointerValue)).ToInt32(); int stringOffset = Marshal.OffsetOf <StructWithReferenceTypes>(nameof(StructWithReferenceTypes.stringValue)).ToInt32(); int arrayOffset = Marshal.OffsetOf <StructWithReferenceTypes>(nameof(StructWithReferenceTypes.byValueArray)).ToInt32(); object structure = new StructWithReferenceTypes { pointerValue = (IntPtr)100, stringValue = "ABC", byValueArray = new int[10] { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10 } }; Marshal.WriteInt32(structure, pointerOffset, 200); Marshal.WriteInt32(structure, arrayOffset + sizeof(int) * 9, 100); Assert.Equal((IntPtr)200, ((StructWithReferenceTypes)structure).pointerValue); Assert.Equal("ABC", ((StructWithReferenceTypes)structure).stringValue); Assert.Equal(new int[10] { 1, 2, 3, 4, 5, 6, 7, 8, 9, 100 }, ((StructWithReferenceTypes)structure).byValueArray); Assert.Equal(200, Marshal.ReadInt32(structure, pointerOffset)); Assert.NotEqual(0, Marshal.ReadInt32(structure, stringOffset)); Assert.Equal(100, Marshal.ReadInt32(structure, arrayOffset + sizeof(int) * 9)); }
public void TestStructWithReferenceType() { StructWithReferenceTypes structWithReferenceTypes = new StructWithReferenceTypes(); structWithReferenceTypes._ptr = new IntPtr(100); structWithReferenceTypes._str = "ABC"; structWithReferenceTypes._byValArr = new int[10] { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10 }; object boxedStruct = (object)structWithReferenceTypes; int offsetOfStr = Marshal.OffsetOf <StructWithReferenceTypes>("_str").ToInt32(); int offsetOfByValArr = Marshal.OffsetOf <StructWithReferenceTypes>("_byValArr").ToInt32(); Assert.Equal(100, Marshal.ReadInt32(boxedStruct, 0)); Assert.NotEqual(IntPtr.Zero, Marshal.ReadIntPtr(boxedStruct, offsetOfStr)); Assert.Equal(3, Marshal.ReadInt32(boxedStruct, offsetOfByValArr + sizeof(int) * 2)); Marshal.WriteInt32(boxedStruct, 0, 200); Marshal.WriteInt32(boxedStruct, offsetOfByValArr + sizeof(int) * 9, 100); Assert.Equal(new IntPtr(200), ((StructWithReferenceTypes)boxedStruct)._ptr); Assert.Equal(100, ((StructWithReferenceTypes)boxedStruct)._byValArr[9]); Assert.Equal(9, ((StructWithReferenceTypes)boxedStruct)._byValArr[8]); Assert.Equal("ABC", ((StructWithReferenceTypes)boxedStruct)._str); }
public void ReadInt16_StructWithReferenceTypes_ReturnsExpected() { int pointerOffset = Marshal.OffsetOf <StructWithReferenceTypes>(nameof(StructWithReferenceTypes.pointerValue)).ToInt32(); int stringOffset = Marshal.OffsetOf <StructWithReferenceTypes>(nameof(StructWithReferenceTypes.stringValue)).ToInt32(); int arrayOffset = Marshal.OffsetOf <StructWithReferenceTypes>(nameof(StructWithReferenceTypes.byValueArray)).ToInt32(); object structure = new StructWithReferenceTypes { pointerValue = (IntPtr)100, stringValue = "ABC", byValueArray = new short[10] { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10 } }; Assert.Equal(100, Marshal.ReadInt16(structure, pointerOffset)); // The ReadInt16() for object types does an explicit marshal which requires // an allocation on each read. It can occur that the allocation is aligned // on a 16-bit boundary which would yield a value of 0. To mitigate the chance, // marshal several times, choosing 20 as an arbitrary value. If this test // fails, we should reconsider whether it is worth the flakiness. int readShorts = 0; for (int i = 0; i < 20; ++i) { readShorts += Marshal.ReadInt16(structure, stringOffset); } Assert.NotEqual(0, readShorts); Assert.Equal(3, Marshal.ReadInt16(structure, arrayOffset + sizeof(short) * 2)); }
public void ReadByte_StructWithReferenceTypes_ReturnsExpected() { int pointerOffset = Marshal.OffsetOf <StructWithReferenceTypes>(nameof(StructWithReferenceTypes.pointerValue)).ToInt32(); int stringOffset = Marshal.OffsetOf <StructWithReferenceTypes>(nameof(StructWithReferenceTypes.stringValue)).ToInt32(); int arrayOffset = Marshal.OffsetOf <StructWithReferenceTypes>(nameof(StructWithReferenceTypes.byValueArray)).ToInt32(); object structure = new StructWithReferenceTypes { pointerValue = (IntPtr)100, stringValue = "ABC", byValueArray = new byte[10] { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10 } }; Assert.Equal(100, Marshal.ReadByte(structure, pointerOffset)); Assert.Equal(3, Marshal.ReadByte(structure, arrayOffset + sizeof(byte) * 2)); }
public void ReadByte_StructWithReferenceTypes_ReturnsExpected() { int pointerOffset = Marshal.OffsetOf <StructWithReferenceTypes>(nameof(StructWithReferenceTypes.pointerValue)).ToInt32(); int stringOffset = Marshal.OffsetOf <StructWithReferenceTypes>(nameof(StructWithReferenceTypes.stringValue)).ToInt32(); int arrayOffset = Marshal.OffsetOf <StructWithReferenceTypes>(nameof(StructWithReferenceTypes.byValueArray)).ToInt32(); object structure = new StructWithReferenceTypes { pointerValue = (IntPtr)100, stringValue = "ABC", byValueArray = new byte[10] { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10 } }; Assert.Equal(100, Marshal.ReadByte(structure, pointerOffset)); // Unlike the Int16/32/64 tests that mirror this one, we aren't going to do any asserts on the value at stringOffset. // The value at stringOffset is a pointer, so it is entirely possible that the first byte is 0. // We tried keeping this test by summing 20 calls, but even that still resulted in 0 too often. As a result, we've // decided to not try to validate this case instead of just incrementally increasing the number of iterations // to avoid getting a 0 value. Assert.Equal(3, Marshal.ReadByte(structure, arrayOffset + sizeof(byte) * 2)); }