Align libgc vcxproj with makefile.
[mono.git] / mono / tests / marshal7.cs
1 using System;
2 using System.Reflection;
3 using System.Runtime.InteropServices;
4
5 public class Test 
6 {
7         [StructLayout(LayoutKind.Sequential, Size=32)]
8         public class TestStruct1 
9         {
10                 public int a;
11         }
12
13         [StructLayout(LayoutKind.Sequential, Size=32)]
14         public class TestStruct2 
15         {
16                 [MarshalAs(UnmanagedType.ByValTStr, SizeConst=16)]
17                 public string   a;
18                 public int              b;
19         }
20
21         [StructLayout(LayoutKind.Sequential, Size=32)]
22         public class TestStruct3 : TestStruct2
23         {
24                 public int              c;
25         }
26
27         [StructLayout (LayoutKind.Sequential)]
28         public class TestStruct4
29         {
30                 [MarshalAs (UnmanagedType.Interface)]
31                 object itf;
32         }
33
34         [StructLayout (LayoutKind.Sequential)]
35         public class TestStruct5
36         {
37                 [MarshalAs (UnmanagedType.IUnknown)]
38                 object itf;
39         }
40
41         [StructLayout (LayoutKind.Sequential)]
42         public class TestStruct6
43         {
44                 [MarshalAs (UnmanagedType.IDispatch)]
45                 object itf;
46         }
47
48         [StructLayout (LayoutKind.Sequential)]
49         public class TestStruct7
50         {
51                 [MarshalAs (UnmanagedType.Struct)]
52                 object itf;
53         }
54
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;
63         }
64
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;
72         }
73
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;
82         }
83
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;
91         }
92
93         [StructLayout (LayoutKind.Explicit, Pack=1)]
94         struct TestStruct12 {
95                 [FieldOffset (0)]
96                 public short a;
97                 [FieldOffset (2)]
98                 public int b;
99         }
100
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;
111         }
112
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;
123         }
124         static bool IsOSX ()
125         {
126                 return (int)typeof (Environment).GetMethod ("get_Platform", BindingFlags.Static | BindingFlags.NonPublic).Invoke (null, null) == 6;
127         }
128
129         public unsafe static int Main () 
130         {
131                 ///
132                 ///     Testing simple struct size
133                 ///
134                 if(Marshal.SizeOf(typeof(TestStruct1)) != 32)
135                 {
136                         return 1;
137                 }
138
139                 TestStruct1 myStruct = new TestStruct1();
140                 myStruct.a = 0x12345678;
141
142                 IntPtr p = Marshal.AllocHGlobal(Marshal.SizeOf(typeof(TestStruct1)));
143                 Marshal.StructureToPtr(myStruct, p, false);
144
145                 Type testType = typeof(TestStruct1);
146                 if (Marshal.ReadInt32(p, (int)Marshal.OffsetOf(testType, "a")) != myStruct.a)
147                         return 2;
148
149                 Marshal.FreeHGlobal(p);
150
151                 ///
152                 ///     Testing struct size with ByValTStr string
153                 ///
154                 if(Marshal.SizeOf(typeof(TestStruct2)) != 32)
155                         return 3;
156
157                 TestStruct2 myStruct2 = new TestStruct2();
158                 myStruct2.b = 0x12345678;
159
160                 p = Marshal.AllocHGlobal(Marshal.SizeOf(typeof(TestStruct2)));
161                 Marshal.StructureToPtr(myStruct2, p, false);
162
163                 Type testType2 = typeof(TestStruct2);
164                 if (Marshal.ReadInt32(p, (int)Marshal.OffsetOf(testType2, "b")) != myStruct2.b)
165                         return 4;
166
167                 Marshal.FreeHGlobal(p);
168
169                 ///
170                 ///     Test structure size and struct with inheritance
171                 ///
172                 if(Marshal.SizeOf(typeof(TestStruct3)) != 64)
173                         return 5;
174
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);
180
181                 Type testType3 = typeof(TestStruct3);
182                 
183                 if(Marshal.ReadInt32(p, (int)Marshal.OffsetOf(testType3, "b")) != myStruct3.b)
184                         return 6;
185
186                 if (Marshal.ReadInt32(p, (int)Marshal.OffsetOf(testType3, "c")) != myStruct3.c) 
187                         return 7;
188
189                 Marshal.FreeHGlobal(p);
190                 
191                 ///
192                 ///     Also make sure OffsetOf returns the correct Exception.
193                 ///
194                 try {
195                         Marshal.OffsetOf(testType3, "blah");
196                         return 8;
197                 }
198                 catch(ArgumentException e)  {
199                         /// Way to go :)
200                 }
201                 catch(Exception e) {
202                         return 9;
203                 }
204
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;
225                 }
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;
237         }
238 }
239