update readme (#21797)
[mono-project.git] / mono / tests / marshal7.cs
blob640f4a04d7822e98699f3a79b4b144833f1bed78
1 using System;
2 using System.Reflection;
3 using System.Runtime.InteropServices;
5 public class Test
7 [StructLayout(LayoutKind.Sequential, Size=32)]
8 public class TestStruct1
10 public int a;
13 [StructLayout(LayoutKind.Sequential, Size=32)]
14 public class TestStruct2
16 [MarshalAs(UnmanagedType.ByValTStr, SizeConst=16)]
17 public string a;
18 public int b;
21 [StructLayout(LayoutKind.Sequential, Size=32)]
22 public class TestStruct3 : TestStruct2
24 public int c;
27 [StructLayout (LayoutKind.Sequential)]
28 public class TestStruct4
30 [MarshalAs (UnmanagedType.Interface)]
31 object itf;
34 [StructLayout (LayoutKind.Sequential)]
35 public class TestStruct5
37 [MarshalAs (UnmanagedType.IUnknown)]
38 object itf;
41 [StructLayout (LayoutKind.Sequential)]
42 public class TestStruct6
44 [MarshalAs (UnmanagedType.IDispatch)]
45 object itf;
48 [StructLayout (LayoutKind.Sequential)]
49 public class TestStruct7
51 [MarshalAs (UnmanagedType.Struct)]
52 object itf;
55 // Size should be 16 in both 32 and 64 bits win/linux
56 // Size should be 12 on 32bits OSX size alignment of long is 4
57 [StructLayout (LayoutKind.Explicit)]
58 struct TestStruct8 {
59 [FieldOffset (0)]
60 public int a;
61 [FieldOffset (4)]
62 public ulong b;
65 // Size should be 12 in both 32 and 64 bits
66 [StructLayout (LayoutKind.Explicit, Size=12)]
67 struct TestStruct9 {
68 [FieldOffset (0)]
69 public int a;
70 [FieldOffset (4)]
71 public ulong b;
74 // Size should be 16 in both 32 and 64 bits
75 // Size should be 12 on 32bits OSX size alignment of long is 4
76 [StructLayout (LayoutKind.Explicit)]
77 struct TestStruct10 {
78 [FieldOffset (0)]
79 public int a;
80 [FieldOffset (3)]
81 public ulong b;
84 // Size should be 11 in both 32 and 64 bits
85 [StructLayout (LayoutKind.Explicit, Size=11)]
86 struct TestStruct11 {
87 [FieldOffset (0)]
88 public int a;
89 [FieldOffset (3)]
90 public ulong b;
93 [StructLayout (LayoutKind.Explicit, Pack=1)]
94 struct TestStruct12 {
95 [FieldOffset (0)]
96 public short a;
97 [FieldOffset (2)]
98 public int b;
101 // Size should always be 12, since pack = 0, size = 0 and min alignment = 4
102 //When pack is not set, we default to 8, so min (8, min alignment) -> 4
103 [StructLayout (LayoutKind.Explicit)]
104 struct TestStruct13 {
105 [FieldOffset(0)]
106 int one;
107 [FieldOffset(4)]
108 int two;
109 [FieldOffset(8)]
110 int three;
113 // Size should always be 12, since pack = 8, size = 0 and min alignment = 4
114 //It's aligned to min (pack, min alignment) -> 4
115 [StructLayout (LayoutKind.Explicit)]
116 struct TestStruct14 {
117 [FieldOffset(0)]
118 int one;
119 [FieldOffset(4)]
120 int two;
121 [FieldOffset(8)]
122 int three;
124 static bool IsOSX ()
126 return (int)typeof (Environment).GetMethod ("get_Platform", BindingFlags.Static | BindingFlags.NonPublic).Invoke (null, null) == 6;
129 public unsafe static int Main ()
132 /// Testing simple struct size
134 if(Marshal.SizeOf(typeof(TestStruct1)) != 32)
136 return 1;
139 TestStruct1 myStruct = new TestStruct1();
140 myStruct.a = 0x12345678;
142 IntPtr p = Marshal.AllocHGlobal(Marshal.SizeOf(typeof(TestStruct1)));
143 Marshal.StructureToPtr(myStruct, p, false);
145 Type testType = typeof(TestStruct1);
146 if (Marshal.ReadInt32(p, (int)Marshal.OffsetOf(testType, "a")) != myStruct.a)
147 return 2;
149 Marshal.FreeHGlobal(p);
152 /// Testing struct size with ByValTStr string
154 if(Marshal.SizeOf(typeof(TestStruct2)) != 32)
155 return 3;
157 TestStruct2 myStruct2 = new TestStruct2();
158 myStruct2.b = 0x12345678;
160 p = Marshal.AllocHGlobal(Marshal.SizeOf(typeof(TestStruct2)));
161 Marshal.StructureToPtr(myStruct2, p, false);
163 Type testType2 = typeof(TestStruct2);
164 if (Marshal.ReadInt32(p, (int)Marshal.OffsetOf(testType2, "b")) != myStruct2.b)
165 return 4;
167 Marshal.FreeHGlobal(p);
170 /// Test structure size and struct with inheritance
172 if(Marshal.SizeOf(typeof(TestStruct3)) != 64)
173 return 5;
175 TestStruct3 myStruct3 = new TestStruct3();
176 myStruct3.b = 0x12345678;
177 myStruct3.c = 0x76543210;
178 p = Marshal.AllocHGlobal(Marshal.SizeOf(typeof(TestStruct3)));
179 Marshal.StructureToPtr(myStruct3, p, false);
181 Type testType3 = typeof(TestStruct3);
183 if(Marshal.ReadInt32(p, (int)Marshal.OffsetOf(testType3, "b")) != myStruct3.b)
184 return 6;
186 if (Marshal.ReadInt32(p, (int)Marshal.OffsetOf(testType3, "c")) != myStruct3.c)
187 return 7;
189 Marshal.FreeHGlobal(p);
192 /// Also make sure OffsetOf returns the correct Exception.
194 try {
195 Marshal.OffsetOf(testType3, "blah");
196 return 8;
198 catch(ArgumentException e) {
199 /// Way to go :)
201 catch(Exception e) {
202 return 9;
205 // test size of structs with objects
206 if (Marshal.SizeOf (typeof (TestStruct4)) != IntPtr.Size)
207 return 10;
208 if (Marshal.SizeOf (typeof (TestStruct5)) != IntPtr.Size)
209 return 11;
210 if (Marshal.SizeOf (typeof (TestStruct6)) != IntPtr.Size)
211 return 12;
212 // a VARIANT is
213 if (Marshal.SizeOf (typeof (TestStruct7)) != 16)
214 return 13;
215 if (IsOSX () && IntPtr.Size == 4) {
216 if (Marshal.SizeOf (typeof (TestStruct8)) != 12)
217 return 14;
218 if (Marshal.SizeOf (typeof (TestStruct10)) != 12)
219 return 16;
220 } else {
221 if (Marshal.SizeOf (typeof (TestStruct8)) != 16 && Marshal.SizeOf (typeof (TestStruct8)) != 12)
222 return 14;
223 if (Marshal.SizeOf (typeof (TestStruct10)) != 16 && Marshal.SizeOf (typeof (TestStruct10)) != 12)
224 return 16;
226 if (Marshal.SizeOf (typeof (TestStruct9)) != 12)
227 return 15;
228 if (Marshal.SizeOf (typeof (TestStruct11)) != 11)
229 return 17;
230 if (Marshal.SizeOf (typeof (TestStruct12)) != 6)
231 return 18;
232 if (Marshal.SizeOf (typeof (TestStruct13)) != 12)
233 return 19;
234 if (Marshal.SizeOf (typeof (TestStruct14)) != 12)
235 return 20;
236 return 0;