New test.
[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 Test {
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         public unsafe static int Main () {
47                 SimpleStruct ss = new SimpleStruct ();
48                 int size = Marshal.SizeOf (typeof (SimpleStruct));
49                 
50                 //if (size != 52)
51                 //return 1;
52                 
53                 IntPtr p = Marshal.AllocHGlobal (size);
54                 ss.a = 1;
55                 ss.bool1 = true;
56                 ss.bool2 = false;
57                 ss.b = 2;
58                 ss.a1 = new short [2];
59                 ss.a1 [0] = 6;
60                 ss.a1 [1] = 5;
61                 ss.s1 = "abcd";
62                 ss.emb1 = new SimpleStruct2 ();
63                 ss.emb1.a = 3;
64                 ss.emb1.b = 4;
65                 ss.emb2 = new SimpleObj ();
66                 ss.emb2.a = 10;
67                 ss.emb2.b = 11;
68                 ss.s2 = "just a test";
69                 ss.x = 1.5;
70                 ss.a2 = new char [2];
71                 ss.a2 [0] = 'a';
72                 ss.a2 [1] = 'b';
73                 
74                 Marshal.StructureToPtr (ss, p, false);
75                 Type t = ss.GetType ();
76                 
77                 if (Marshal.ReadInt32 (p, (int)Marshal.OffsetOf (t, "a")) != 1)
78                         return 1;
79                 if (Marshal.ReadInt32 (p, (int)Marshal.OffsetOf (t, "bool1")) != 1)
80                         return 2;
81                 if (Marshal.ReadInt32 (p, (int)Marshal.OffsetOf (t, "bool2")) != 0)
82                         return 3;
83                 if (Marshal.ReadInt32 (p, (int)Marshal.OffsetOf (t, "b")) != 2)
84                         return 4;
85                 if (Marshal.ReadInt16 (p, 16) != 6)
86                         return 5;
87                 if (Marshal.ReadInt16 (p, 18) != 5)
88                         return 6;
89                 if (Marshal.ReadByte (p, 20) != 97)
90                         return 7;
91                 if (Marshal.ReadByte (p, 21) != 98)
92                         return 8;
93                 if (Marshal.ReadByte (p, 22) != 99)
94                         return 9;
95                 if (Marshal.ReadByte (p, 23) != 0)
96                         return 10;
97                 if (Marshal.ReadInt32 (p, 24) != 3)
98                         return 11;
99                 if (Marshal.ReadInt32 (p, 28) != 4)
100                         return 12;
101                 if (Marshal.ReadInt32 (p, 32) != 10)
102                         return 13;
103                 if (Marshal.ReadInt32 (p, 36) != 11)
104                         return 14;
105                 if (Marshal.ReadByte (p, (int)Marshal.OffsetOf (t, "a2")) != 97)
106                         return 15;
107                 if (Marshal.ReadByte (p, (int)Marshal.OffsetOf (t, "a2") + 1) != 98)
108                         return 16;
109
110                 SimpleStruct cp = (SimpleStruct)Marshal.PtrToStructure (p, ss.GetType ());
111
112                 if (cp.a != 1)
113                         return 16;
114
115                 if (cp.bool1 != true)
116                         return 17;
117
118                 if (cp.bool2 != false)
119                         return 18;
120
121                 if (cp.b != 2)
122                         return 19;
123
124                 if (cp.a1 [0] != 6)
125                         return 20;
126                 
127                 if (cp.a1 [1] != 5)
128                         return 21;
129
130                 if (cp.s1 != "abc")
131                         return 22;
132                 
133                 if (cp.emb1.a != 3)
134                         return 23;
135
136                 if (cp.emb1.b != 4)
137                         return 24;
138
139                 if (cp.emb2.a != 10)
140                         return 25;
141
142                 if (cp.emb2.b != 11)
143                         return 26;
144
145                 if (cp.s2 != "just a test")
146                         return 27;
147
148                 if (cp.x != 1.5)
149                         return 28;
150
151                 if (cp.a2 [0] != 'a')
152                         return 29;
153
154                 if (cp.a2 [1] != 'b')
155                         return 30;
156
157                 /* ByValTStr with Unicode */
158                 ByValWStrStruct s = new ByValWStrStruct ();
159
160                 IntPtr p2 = Marshal.AllocHGlobal (Marshal.SizeOf (typeof (ByValWStrStruct)));
161                 Marshal.StructureToPtr(s, p2, false);
162
163                 /* Check that the ByValWStr is initialized correctly */
164                 for (int i = 0; i < 8; ++i)
165                         if (Marshal.ReadByte (p2, i) != 0)
166                                 return 31;
167
168                 s.s1 = "ABCD";
169                 s.i = 55;
170
171                 Marshal.StructureToPtr(s, p2, false);
172
173                 ByValWStrStruct s2 = (ByValWStrStruct)Marshal.PtrToStructure (p2, typeof (ByValWStrStruct));
174
175                 /* The fourth char is lost because of null-termination */
176                 if (s2.s1 != "ABC")
177                         return 32;
178
179                 if (s2.i != 55)
180                         return 33;
181
182                 return 0;
183         }
184 }
185