Merge pull request #799 from kebby/master
[mono.git] / mono / tests / marshal2.cs
1 //
2 // Tests for Marshal.StructureToPtr and PtrToStructure
3 //
4
5 using System;
6 using System.Runtime.InteropServices;
7
8 public class Tests {
9
10
11         [StructLayout (LayoutKind.Sequential)]
12         public class SimpleObj {
13                 public int a;
14                 public int b;
15
16                 public void test () {}
17         }
18
19         [StructLayout (LayoutKind.Sequential)]
20         public struct SimpleStruct2 {
21                 public int a;
22                 public int b;
23         }
24         
25         [StructLayout (LayoutKind.Sequential, CharSet=CharSet.Ansi)]
26         public struct SimpleStruct {
27                 public int a;
28                 public bool bool1;
29                 public bool bool2;
30                 public int b;
31                 [MarshalAs (UnmanagedType.ByValArray, SizeConst=2)] public short[] a1;
32                 [MarshalAs (UnmanagedType.ByValTStr, SizeConst=4)] public string s1;
33                 public SimpleStruct2 emb1;
34                 public SimpleObj emb2;
35                 public string s2;
36                 public double x;
37                 [MarshalAs (UnmanagedType.ByValArray, SizeConst=2)] public char[] a2;
38         }
39
40         [StructLayout (LayoutKind.Sequential, CharSet=CharSet.Unicode)]
41         public struct ByValWStrStruct {
42                 [MarshalAs (UnmanagedType.ByValTStr, SizeConst=4)] public string s1;
43                 public int i;
44         }
45
46         [StructLayout (LayoutKind.Sequential, Pack=1)]
47         public struct PackStruct1 {
48                 float f;
49         }
50
51         [StructLayout (LayoutKind.Sequential)]
52         public struct PackStruct2 {
53                 byte b;
54                 PackStruct1 s;
55         }
56         
57         public unsafe static int Main (String[] args) {
58                 if (TestDriver.RunTests (typeof (Tests), args) != 0)
59                         return 34;
60                 return 0;
61         }
62
63         public static int test_0_structure_to_ptr () {
64                 SimpleStruct ss = new SimpleStruct ();
65                 int size = Marshal.SizeOf (typeof (SimpleStruct));
66                 
67                 //if (size != 52)
68                 //return 1;
69                 
70                 IntPtr p = Marshal.AllocHGlobal (size);
71                 ss.a = 1;
72                 ss.bool1 = true;
73                 ss.bool2 = false;
74                 ss.b = 2;
75                 ss.a1 = new short [2];
76                 ss.a1 [0] = 6;
77                 ss.a1 [1] = 5;
78                 ss.s1 = "abcd";
79                 ss.emb1 = new SimpleStruct2 ();
80                 ss.emb1.a = 3;
81                 ss.emb1.b = 4;
82                 ss.emb2 = new SimpleObj ();
83                 ss.emb2.a = 10;
84                 ss.emb2.b = 11;
85                 ss.s2 = "just a test";
86                 ss.x = 1.5;
87                 ss.a2 = new char [2];
88                 ss.a2 [0] = 'a';
89                 ss.a2 [1] = 'b';
90                 
91                 Marshal.StructureToPtr (ss, p, false);
92                 Type t = ss.GetType ();
93                 
94                 if (Marshal.ReadInt32 (p, (int)Marshal.OffsetOf (t, "a")) != 1)
95                         return 1;
96                 if (Marshal.ReadInt32 (p, (int)Marshal.OffsetOf (t, "bool1")) != 1)
97                         return 2;
98                 if (Marshal.ReadInt32 (p, (int)Marshal.OffsetOf (t, "bool2")) != 0)
99                         return 3;
100                 if (Marshal.ReadInt32 (p, (int)Marshal.OffsetOf (t, "b")) != 2)
101                         return 4;
102                 if (Marshal.ReadInt16 (p, 16) != 6)
103                         return 5;
104                 if (Marshal.ReadInt16 (p, 18) != 5)
105                         return 6;
106                 if (Marshal.ReadByte (p, 20) != 97)
107                         return 7;
108                 if (Marshal.ReadByte (p, 21) != 98)
109                         return 8;
110                 if (Marshal.ReadByte (p, 22) != 99)
111                         return 9;
112                 if (Marshal.ReadByte (p, 23) != 0)
113                         return 10;
114                 if (Marshal.ReadInt32 (p, 24) != 3)
115                         return 11;
116                 if (Marshal.ReadInt32 (p, 28) != 4)
117                         return 12;
118                 if (Marshal.ReadInt32 (p, 32) != 10)
119                         return 13;
120                 if (Marshal.ReadInt32 (p, 36) != 11)
121                         return 14;
122                 if (Marshal.ReadByte (p, (int)Marshal.OffsetOf (t, "a2")) != 97)
123                         return 15;
124                 if (Marshal.ReadByte (p, (int)Marshal.OffsetOf (t, "a2") + 1) != 98)
125                         return 16;
126
127                 SimpleStruct cp = (SimpleStruct)Marshal.PtrToStructure (p, ss.GetType ());
128
129                 if (cp.a != 1)
130                         return 16;
131
132                 if (cp.bool1 != true)
133                         return 17;
134
135                 if (cp.bool2 != false)
136                         return 18;
137
138                 if (cp.b != 2)
139                         return 19;
140
141                 if (cp.a1 [0] != 6)
142                         return 20;
143                 
144                 if (cp.a1 [1] != 5)
145                         return 21;
146
147                 if (cp.s1 != "abc")
148                         return 22;
149                 
150                 if (cp.emb1.a != 3)
151                         return 23;
152
153                 if (cp.emb1.b != 4)
154                         return 24;
155
156                 if (cp.emb2.a != 10)
157                         return 25;
158
159                 if (cp.emb2.b != 11)
160                         return 26;
161
162                 if (cp.s2 != "just a test")
163                         return 27;
164
165                 if (cp.x != 1.5)
166                         return 28;
167
168                 if (cp.a2 [0] != 'a')
169                         return 29;
170
171                 if (cp.a2 [1] != 'b')
172                         return 30;
173                 return 0;
174         }
175
176         [StructLayout(LayoutKind.Sequential, Pack = 1, CharSet = CharSet.Unicode)]
177         public struct Struct1
178         {
179                 [MarshalAs(UnmanagedType.ByValTStr, SizeConst = 8)]
180         public string Field1;
181                 [MarshalAs(UnmanagedType.ByValTStr, SizeConst = 10)]
182         public string Field2;
183                 [MarshalAs(UnmanagedType.ByValTStr, SizeConst = 14)]
184         public string Field3;
185         }
186
187         public static int test_0_byvaltstr_unicode () {
188                 ByValWStrStruct s = new ByValWStrStruct ();
189
190                 IntPtr p2 = Marshal.AllocHGlobal (Marshal.SizeOf (typeof (ByValWStrStruct)));
191                 Marshal.StructureToPtr(s, p2, false);
192
193                 /* Check that the ByValWStr is initialized correctly */
194                 for (int i = 0; i < 8; ++i)
195                         if (Marshal.ReadByte (p2, i) != 0)
196                                 return 31;
197
198                 s.s1 = "ABCD";
199                 s.i = 55;
200
201                 Marshal.StructureToPtr(s, p2, false);
202
203                 ByValWStrStruct s2 = (ByValWStrStruct)Marshal.PtrToStructure (p2, typeof (ByValWStrStruct));
204
205                 /* The fourth char is lost because of null-termination */
206                 if (s2.s1 != "ABC")
207                         return 32;
208
209                 if (s2.i != 55)
210                         return 33;
211                 return 0;
212         }
213
214         public static int test_0_byvaltstr_max_size () {
215                 string buffer = "12345678123456789012345678901234";
216
217                 IntPtr ptr = Marshal.StringToBSTR (buffer);
218
219                 Struct1 data = (Struct1)Marshal.PtrToStructure (ptr, typeof (Struct1));
220                 if (data.Field1 != "12345678")
221                         return 1;
222                 if (data.Field2 != "1234567890")
223                         return 2;
224                 if (data.Field3 != "12345678901234")
225                         return 3;
226                 return 0;
227         }
228
229         // Check that the 'Pack' directive on a struct changes the min alignment of the struct as well (#12110)
230         public static int test_0_struct_pack () {
231                 if (Marshal.OffsetOf (typeof (PackStruct2), "s") != new IntPtr (1))
232                         return 1;
233                 return 0;
234         }
235 }