2 using System
.Runtime
.InteropServices
;
3 using System
.Reflection
;
6 public struct EmptyStruct
{
9 [StructLayout(LayoutKind
.Sequential
)]
10 public struct EmptySequentialStruct
{
13 [StructLayout(LayoutKind
.Explicit
)]
14 public struct EmptyExplicitStruct
{
17 [StructLayout(LayoutKind
.Sequential
, Pack
= 4)]
18 public struct EmptySequentialPackStruct
{
21 [StructLayout(LayoutKind
.Explicit
, Pack
= 4)]
22 public struct EmptyExplicitPackStruct
{
25 [StructLayout(LayoutKind
.Explicit
, Size
= 0)]
26 public struct EmptyExplicitSize0Struct
{
29 [StructLayout(LayoutKind
.Explicit
, Size
= 1)]
30 public struct EmptyExplicitSize1Struct
{
33 [StructLayout(LayoutKind
.Sequential
, Pack
= 1)]
34 public struct TestOffsets
{
38 public EmptyExplicitSize0Struct D
;
40 public EmptySequentialStruct F
;
45 private static unsafe void CheckSize
<T
> (int expected
, ref int exitCode
) {
47 var actualSize
= Marshal
.SizeOf(t
);
49 Console
.WriteLine($"Marshal.SizeOf({t.Name}) == {actualSize}, expected {expected}");
51 if (actualSize
!= expected
)
55 // https://bugzilla.xamarin.com/show_bug.cgi?id=18941
56 // Marshal.SizeOf should never report 0, even for empty structs or structs with Size=0 attribute
57 public static int Main () {
60 CheckSize
<EmptyStruct
>(1, ref exitCode
);
61 CheckSize
<EmptySequentialStruct
>(1, ref exitCode
);
62 CheckSize
<EmptyExplicitStruct
>(1, ref exitCode
);
63 CheckSize
<EmptySequentialPackStruct
>(1, ref exitCode
);
64 CheckSize
<EmptyExplicitPackStruct
>(1, ref exitCode
);
65 CheckSize
<EmptyExplicitSize0Struct
>(1, ref exitCode
);
66 CheckSize
<EmptyExplicitSize1Struct
>(1, ref exitCode
);
67 CheckSize
<TestOffsets
>(19, ref exitCode
);
69 Console
.WriteLine("--");
71 var t
= typeof(TestOffsets
);
73 from f
in t
.GetFields()
74 select (name
: f
.Name
, offset
: Marshal
.OffsetOf(t
, f
.Name
).ToInt32())
77 var expectedOffsets
= new [] {
78 (name
: "A", offset
: 0),
79 (name
: "B", offset
: 4),
80 (name
: "C", offset
: 5),
81 (name
: "D", offset
: 9),
82 (name
: "E", offset
: 10),
83 (name
: "F", offset
: 14),
84 (name
: "G", offset
: 15)
87 if (!actualOffsets
.SequenceEqual(expectedOffsets
)) {
88 Console
.WriteLine("Field offset mismatch:");
90 for (int i
= 0; i
< expectedOffsets
.Length
; i
++) {
91 var expected
= expectedOffsets
[i
];
92 var actual
= actualOffsets
[i
];
93 Console
.WriteLine($"OffsetOf({t.Name}.{actual.name}) == {actual.offset}, expected OffsetOf({expected.name}) == {expected.offset}.");