[tests] Test loading references from LoadFrom and LoadFile contexts
[mono-project.git] / mono / tests / marshal2.cs
blob7707b32dbb8bd713ddf0a43dede02438fb82095c
1 //
2 // Tests for Marshal.StructureToPtr and PtrToStructure
3 //
5 using System;
6 using System.Text;
7 using System.Runtime.InteropServices;
9 public class Tests {
12 [StructLayout (LayoutKind.Sequential)]
13 public class SimpleObj {
14 public int a;
15 public int b;
17 public void test () {}
20 [StructLayout (LayoutKind.Sequential)]
21 public struct SimpleStruct2 {
22 public int a;
23 public int b;
26 [StructLayout (LayoutKind.Sequential, CharSet=CharSet.Ansi)]
27 public struct SimpleStruct {
28 public int a;
29 public bool bool1;
30 public bool bool2;
31 public int b;
32 [MarshalAs (UnmanagedType.ByValArray, SizeConst=2)] public short[] a1;
33 [MarshalAs (UnmanagedType.ByValTStr, SizeConst=4)] public string s1;
34 public SimpleStruct2 emb1;
35 public SimpleObj emb2;
36 public string s2;
37 public double x;
38 [MarshalAs (UnmanagedType.ByValArray, SizeConst=2)] public char[] a2;
41 [StructLayout (LayoutKind.Sequential, CharSet=CharSet.Ansi)]
42 public struct ByValTStrStruct {
43 [MarshalAs (UnmanagedType.ByValTStr, SizeConst=4)] public string s1;
44 public int i;
47 [StructLayout (LayoutKind.Sequential, CharSet=CharSet.Unicode)]
48 public struct ByValWStrStruct {
49 [MarshalAs (UnmanagedType.ByValTStr, SizeConst=4)] public string s1;
50 public int i;
53 [StructLayout (LayoutKind.Sequential, Pack=1)]
54 public struct PackStruct1 {
55 float f;
58 [StructLayout (LayoutKind.Sequential)]
59 public struct PackStruct2 {
60 byte b;
61 PackStruct1 s;
64 [StructLayout (LayoutKind.Sequential)]
65 struct InvalidArrayForMarshalingStruct
67 // Missing the following needed directive
68 // [MarshalAs(UnmanagedType.ByValArray, SizeConst = 4)]
69 public readonly char[] CharArray;
72 [StructLayout(LayoutKind.Sequential)]
73 struct TwoDimensionalArrayStruct
75 public TwoDimensionalArrayStruct(int[,] vals)
77 TwoDimensionalArray = vals;
80 [MarshalAs(UnmanagedType.ByValArray, SizeConst = 6)]
81 public readonly int[,] TwoDimensionalArray;
84 public unsafe static int Main (String[] args) {
85 if (TestDriver.RunTests (typeof (Tests), args) != 0)
86 return 34;
87 return 0;
90 public static int test_0_structure_to_ptr () {
91 SimpleStruct ss = new SimpleStruct ();
92 int size = Marshal.SizeOf (typeof (SimpleStruct));
94 //if (size != 52)
95 //return 1;
97 IntPtr p = Marshal.AllocHGlobal (size);
98 ss.a = 1;
99 ss.bool1 = true;
100 ss.bool2 = false;
101 ss.b = 2;
102 ss.a1 = new short [2];
103 ss.a1 [0] = 6;
104 ss.a1 [1] = 5;
105 ss.s1 = "abcd";
106 ss.emb1 = new SimpleStruct2 ();
107 ss.emb1.a = 3;
108 ss.emb1.b = 4;
109 ss.emb2 = new SimpleObj ();
110 ss.emb2.a = 10;
111 ss.emb2.b = 11;
112 ss.s2 = "just a test";
113 ss.x = 1.5;
114 ss.a2 = new char [2];
115 ss.a2 [0] = 'a';
116 ss.a2 [1] = 'b';
118 Marshal.StructureToPtr (ss, p, false);
119 Type t = ss.GetType ();
121 if (Marshal.ReadInt32 (p, (int)Marshal.OffsetOf (t, "a")) != 1)
122 return 1;
123 if (Marshal.ReadInt32 (p, (int)Marshal.OffsetOf (t, "bool1")) != 1)
124 return 2;
125 if (Marshal.ReadInt32 (p, (int)Marshal.OffsetOf (t, "bool2")) != 0)
126 return 3;
127 if (Marshal.ReadInt32 (p, (int)Marshal.OffsetOf (t, "b")) != 2)
128 return 4;
129 if (Marshal.ReadInt16 (p, 16) != 6)
130 return 5;
131 if (Marshal.ReadInt16 (p, 18) != 5)
132 return 6;
133 if (Marshal.ReadByte (p, 20) != 97)
134 return 7;
135 if (Marshal.ReadByte (p, 21) != 98)
136 return 8;
137 if (Marshal.ReadByte (p, 22) != 99)
138 return 9;
139 if (Marshal.ReadByte (p, 23) != 0)
140 return 10;
141 if (Marshal.ReadInt32 (p, 24) != 3)
142 return 11;
143 if (Marshal.ReadInt32 (p, 28) != 4)
144 return 12;
145 if (Marshal.ReadInt32 (p, 32) != 10)
146 return 13;
147 if (Marshal.ReadInt32 (p, 36) != 11)
148 return 14;
149 if (Marshal.ReadByte (p, (int)Marshal.OffsetOf (t, "a2")) != 97)
150 return 15;
151 if (Marshal.ReadByte (p, (int)Marshal.OffsetOf (t, "a2") + 1) != 98)
152 return 16;
154 SimpleStruct cp = (SimpleStruct)Marshal.PtrToStructure (p, ss.GetType ());
156 if (cp.a != 1)
157 return 16;
159 if (cp.bool1 != true)
160 return 17;
162 if (cp.bool2 != false)
163 return 18;
165 if (cp.b != 2)
166 return 19;
168 if (cp.a1 [0] != 6)
169 return 20;
171 if (cp.a1 [1] != 5)
172 return 21;
174 if (cp.s1 != "abc")
175 return 22;
177 if (cp.emb1.a != 3)
178 return 23;
180 if (cp.emb1.b != 4)
181 return 24;
183 if (cp.emb2.a != 10)
184 return 25;
186 if (cp.emb2.b != 11)
187 return 26;
189 if (cp.s2 != "just a test")
190 return 27;
192 if (cp.x != 1.5)
193 return 28;
195 if (cp.a2 [0] != 'a')
196 return 29;
198 if (cp.a2 [1] != 'b')
199 return 30;
200 return 0;
203 [StructLayout(LayoutKind.Sequential, Pack = 1, CharSet = CharSet.Unicode)]
204 public struct Struct1
206 [MarshalAs(UnmanagedType.ByValTStr, SizeConst = 8)]
207 public string Field1;
208 [MarshalAs(UnmanagedType.ByValTStr, SizeConst = 10)]
209 public string Field2;
210 [MarshalAs(UnmanagedType.ByValTStr, SizeConst = 14)]
211 public string Field3;
214 public static int test_0_byvaltstr () {
215 ByValTStrStruct s = new ByValTStrStruct ();
217 IntPtr p2 = Marshal.AllocHGlobal (Marshal.SizeOf (typeof (ByValTStrStruct)));
218 Marshal.StructureToPtr(s, p2, false);
220 /* Check that the ByValTStr is initialized correctly */
221 for (int i = 0; i < 4; ++i)
222 if (Marshal.ReadByte (p2, i) != 0)
223 return 31;
225 s.s1 = "ABCD";
226 s.i = 55;
228 Marshal.StructureToPtr(s, p2, false);
230 ByValTStrStruct s2 = (ByValTStrStruct)Marshal.PtrToStructure (p2, typeof (ByValTStrStruct));
232 /* The fourth char is lost because of null-termination */
233 if (s2.s1 != "ABC")
234 return 32;
236 if (s2.i != 55)
237 return 33;
239 // Check that decoding also respects the size, even when there is no null terminator
240 byte[] data = Encoding.ASCII.GetBytes ("ABCDXXXX");
241 int size = Marshal.SizeOf (typeof (ByValTStrStruct));
242 IntPtr buffer = Marshal.AllocHGlobal (size);
243 Marshal.Copy (data, 0, buffer, size);
245 s2 = (ByValTStrStruct)Marshal.PtrToStructure (buffer, typeof (ByValTStrStruct));
246 if (s2.s1 != "ABC")
247 return 34;
249 return 0;
252 public static int test_0_byvaltstr_unicode () {
253 ByValWStrStruct s = new ByValWStrStruct ();
255 IntPtr p2 = Marshal.AllocHGlobal (Marshal.SizeOf (typeof (ByValWStrStruct)));
256 Marshal.StructureToPtr(s, p2, false);
258 /* Check that the ByValWStr is initialized correctly */
259 for (int i = 0; i < 8; ++i)
260 if (Marshal.ReadByte (p2, i) != 0)
261 return 31;
263 s.s1 = "ABCD";
264 s.i = 55;
266 Marshal.StructureToPtr(s, p2, false);
268 ByValWStrStruct s2 = (ByValWStrStruct)Marshal.PtrToStructure (p2, typeof (ByValWStrStruct));
270 /* The fourth char is lost because of null-termination */
271 if (s2.s1 != "ABC")
272 return 32;
274 if (s2.i != 55)
275 return 33;
276 return 0;
279 public static int test_0_byvaltstr_max_size () {
280 string buffer = "12345678123456789012345678901234";
282 IntPtr ptr = Marshal.StringToBSTR (buffer);
284 Struct1 data = (Struct1)Marshal.PtrToStructure (ptr, typeof (Struct1));
285 if (data.Field1 != "12345678")
286 return 1;
287 if (data.Field2 != "1234567890")
288 return 2;
289 if (data.Field3 != "12345678901234")
290 return 3;
291 return 0;
294 // Check that the 'Pack' directive on a struct changes the min alignment of the struct as well (#12110)
295 public static int test_0_struct_pack () {
296 if (Marshal.OffsetOf (typeof (PackStruct2), "s") != new IntPtr (1))
297 return 1;
298 return 0;
301 public static int test_0_generic_ptr_to_struct () {
302 int size = Marshal.SizeOf (typeof (SimpleStruct2));
303 IntPtr p = Marshal.AllocHGlobal (size);
305 Marshal.WriteInt32 (p, 0, 1); //a
306 Marshal.WriteInt32 (p, 4, 2); //a
308 var s = Marshal.PtrToStructure<SimpleStruct2> (p);
310 if (s.a != 1)
311 return 1;
312 if (s.b != 2)
313 return 2;
314 return 0;
317 public static int test_0_invalid_array_throws () {
318 var ptr = Marshal.AllocHGlobal(Marshal.SizeOf (typeof (InvalidArrayForMarshalingStruct)));
319 try {
320 Marshal.PtrToStructure (ptr, typeof (InvalidArrayForMarshalingStruct));
322 catch (MarshalDirectiveException e) {
323 return 0;
325 return 1;
328 public static int test_0_multidimentional_arrays () {
329 var structToMarshal = new TwoDimensionalArrayStruct (new[, ] { {1, 2, 3}, {4, 5, 6} });
330 var ptr = Marshal.AllocHGlobal (Marshal.SizeOf (structToMarshal));
331 Marshal.StructureToPtr (structToMarshal, ptr, false);
332 unsafe {
333 if(((int*)ptr)[4] == 5)
334 return 0;
336 return 1;