New test.
[mono.git] / mono / tests / marshal9.cs
1 //
2 // marshal9.cs: tests for custom marshalling
3 //
4
5 using System;
6 using System.Runtime.InteropServices;
7
8 public class Marshal1 : ICustomMarshaler
9 {
10         int param;
11
12         public static int cleanup_managed_count = 0;
13
14         public static int cleanup_native_count = 0;
15
16         public static int native_to_managed_count = 0;
17
18         public static object native_to_managed_result = null;
19
20         public Marshal1 (int param) {
21                 this.param = param;
22         }
23
24         public static ICustomMarshaler GetInstance (string s) {
25                 int param = Int32.Parse (s);
26                 return new Marshal1 (param);
27         }
28
29         public void CleanUpManagedData (object managedObj)
30         {
31                 //Console.WriteLine ("CleanUpManagedData called");
32                 cleanup_managed_count ++;
33         }
34
35         public void CleanUpNativeData (IntPtr pNativeData)
36         {
37                 //Console.WriteLine("CleanUpNativeData:" + pNativeData);
38                 /* Might be allocated in libtest.c using g_new0 so dont free it */
39                 int alloc_type = Marshal.ReadInt32 (pNativeData);
40                 if (alloc_type == 1)
41                         Marshal.FreeHGlobal (pNativeData);
42                 cleanup_native_count ++;
43         }
44
45         // I really do not understand the purpose of this method
46         // or when it would be called. In fact, Rotor never seems
47         // to call it.
48         public int GetNativeDataSize ()
49         {
50                 //Console.WriteLine("GetNativeDataSize() called");
51                 return 4;
52         }
53
54         public IntPtr MarshalManagedToNative (object managedObj)
55         {
56                 int number;
57                 IntPtr ptr;
58
59                 number = Convert.ToInt32 (managedObj);
60                 ptr = Marshal.AllocHGlobal (8);
61                 Marshal.WriteInt32 (ptr, 1);  /* Allocated by AllocHGlobal */
62                 Marshal.WriteInt32(new IntPtr (ptr.ToInt64 () + 4), number);
63
64                 //Console.WriteLine ("ToNative: " + ptr);
65                 return ptr;
66         }
67
68         public object MarshalNativeToManaged (IntPtr pNativeData)
69         {
70                 //Console.WriteLine ("ToManaged: " + pNativeData);
71                 native_to_managed_count ++;
72                 native_to_managed_result = param + Marshal.ReadInt32 (new IntPtr (pNativeData.ToInt64 () + 4));
73                 return native_to_managed_result;
74         }
75 }
76
77 public class Tests
78 {
79         public static int Main (string[] args) {
80                 return TestDriver.RunTests (typeof (Tests));
81         }
82
83         [DllImport ("libtest")]
84         [return : MarshalAs(UnmanagedType.CustomMarshaler,MarshalTypeRef = typeof
85                                                 (Marshal1), MarshalCookie = "5")]
86         private static extern object mono_test_marshal_pass_return_custom (int i,  
87                                                                                                                                         [MarshalAs( UnmanagedType.CustomMarshaler, MarshalTypeRef = typeof (Marshal1), MarshalCookie = "5")] object number, int j);
88
89         public static int test_0_pass_return () {
90
91                 Marshal1.cleanup_managed_count = 0;
92                 Marshal1.cleanup_native_count = 0;
93
94                 int res = (int)mono_test_marshal_pass_return_custom (5, 10, 5);
95
96                 if (Marshal1.cleanup_managed_count != 0)
97                         return 1;
98                 if (Marshal1.cleanup_native_count != 2)
99                         return 2;
100
101                 return res == 15 ? 0 : 3;
102         }
103
104         [DllImport ("libtest")]
105         private static extern int mono_test_marshal_pass_out_custom (int i,  
106                                                                                                                         [MarshalAs( UnmanagedType.CustomMarshaler, MarshalTypeRef = typeof (Marshal1), MarshalCookie = "5"), Out] out object number, int j);
107
108         public static int test_0_pass_out () {
109
110                 Marshal1.cleanup_managed_count = 0;
111                 Marshal1.cleanup_native_count = 0;
112
113                 object o = 0;
114                 int res = mono_test_marshal_pass_out_custom (5, out o, 5);
115
116                 /* 10 + 5 + 5 + 5 */
117                 if ((int)o != 25)
118                         return 1;
119
120                 if (Marshal1.cleanup_managed_count != 0)
121                         return 2;
122                 if (Marshal1.cleanup_native_count != 1)
123                         return 3;
124
125                 return 0;
126         }
127
128         [DllImport ("libtest")]
129         private static extern int mono_test_marshal_pass_inout_custom (int i,
130                                                                                                                         [MarshalAs( UnmanagedType.CustomMarshaler, MarshalTypeRef = typeof (Marshal1), MarshalCookie = "5"), In, Out] object number, int j);
131
132         public static int test_0_pass_inout () {
133                 Marshal1.cleanup_managed_count = 0;
134                 Marshal1.cleanup_native_count = 0;
135                 Marshal1.native_to_managed_result = null;
136
137                 int res = mono_test_marshal_pass_inout_custom (5, 5, 5);
138
139                 // The changes made by the [Out] custom marshaller are not visible to the caller
140                 if ((int)Marshal1.native_to_managed_result != 20)
141                         return 1;
142
143                 if (Marshal1.cleanup_managed_count != 0)
144                         return 2;
145                 if (Marshal1.cleanup_native_count != 1)
146                         return 3;
147
148                 return 0;
149         }
150
151         [DllImport ("libtest")]
152         private static extern int mono_test_marshal_pass_out_byval_custom (int i,
153                                                                                                                         [MarshalAs( UnmanagedType.CustomMarshaler, MarshalTypeRef = typeof (Marshal1), MarshalCookie = "5"), Out] object number, int j);
154
155         public static int test_0_pass_out_byval () {
156                 Marshal1.cleanup_managed_count = 0;
157                 Marshal1.cleanup_native_count = 0;
158                 Marshal1.native_to_managed_result = null;
159
160                 // MS.NET passes NULL and does no marshalling in this case
161                 int res = mono_test_marshal_pass_out_byval_custom (5, 5, 5);
162
163                 if (res != 0)
164                         return 1;
165
166                 if (Marshal1.native_to_managed_result != null)
167                         return 2;
168
169                 if (Marshal1.cleanup_managed_count != 0)
170                         return 3;
171                 if (Marshal1.cleanup_native_count != 0)
172                         return 4;
173
174                 return 0;
175         }
176
177         [DllImport ("libtest")]
178         private static extern int mono_test_marshal_pass_byref_custom (int i,  
179                                                                                                                         [MarshalAs( UnmanagedType.CustomMarshaler, MarshalTypeRef = typeof (Marshal1), MarshalCookie = "5")] ref object number, int j);
180
181         public static int test_0_pass_ref () {
182
183                 Marshal1.cleanup_managed_count = 0;
184                 Marshal1.cleanup_native_count = 0;
185
186                 object o = 10;
187                 int res = mono_test_marshal_pass_byref_custom (5, ref o, 5);
188
189                 /* 10 + 5 + 5 + 5 */
190                 if ((int)o != 25)
191                         return 1;
192
193                 if (Marshal1.cleanup_managed_count != 0)
194                         return 2;
195                 if (Marshal1.cleanup_native_count != 1)
196                         return 3;
197
198                 return 0;
199         }
200
201         [DllImport ("libtest")]
202         [return : MarshalAs(UnmanagedType.CustomMarshaler,MarshalTypeRef = typeof
203                                                 (Marshal1), MarshalCookie = "5")]
204         private static extern object mono_test_marshal_pass_return_custom_null (int i,  
205                                                                                                                                         [MarshalAs( UnmanagedType.CustomMarshaler, MarshalTypeRef = typeof (Marshal1), MarshalCookie = "5")] object number, int j);
206
207         public static int test_0_pass_return_null () {
208
209                 Marshal1.cleanup_managed_count = 0;
210                 Marshal1.cleanup_native_count = 0;
211
212                 object o = mono_test_marshal_pass_return_custom_null (5, null, 5);
213
214                 if (Marshal1.cleanup_managed_count != 0)
215                         return 1;
216                 if (Marshal1.cleanup_native_count != 0)
217                         return 2;
218
219                 return (o == null) ? 0 : 1;
220         }
221
222         [return : MarshalAs(UnmanagedType.CustomMarshaler,MarshalTypeRef = typeof
223 (Marshal1), MarshalCookie = "5")] public delegate object pass_return_int_delegate ([MarshalAs (UnmanagedType.CustomMarshaler, MarshalTypeRef = typeof (Marshal1), MarshalCookie = "5")] object o);
224
225         [DllImport ("libtest")]
226         private static extern int mono_test_marshal_pass_return_custom_in_delegate (pass_return_int_delegate del);
227
228         [DllImport ("libtest")]
229         private static extern int mono_test_marshal_pass_return_custom_null_in_delegate (pass_return_int_delegate del);
230
231         private static object pass_return_int (object i) {
232                 return (int)i;
233         }
234
235         private static object pass_return_null (object i) {
236                 return (i == null) ? null : new Object ();
237         }
238
239         public static int test_0_pass_return_delegate () {
240
241                 Marshal1.cleanup_managed_count = 0;
242                 Marshal1.cleanup_native_count = 0;
243
244                 int res = mono_test_marshal_pass_return_custom_in_delegate (new pass_return_int_delegate (pass_return_int));
245
246                 if (Marshal1.cleanup_managed_count != 2)
247                         return 1;
248                 if (Marshal1.cleanup_native_count != 0)
249                         return 2;
250
251                 return res == 15 ? 0 : 3;
252         }
253
254         public static int test_0_pass_return_null_delegate () {
255
256                 Marshal1.cleanup_managed_count = 0;
257                 Marshal1.cleanup_native_count = 0;
258
259                 int res = mono_test_marshal_pass_return_custom_null_in_delegate (new pass_return_int_delegate (pass_return_null));
260
261                 if (Marshal1.cleanup_managed_count != 0)
262                         return 1;
263                 if (Marshal1.cleanup_native_count != 0)
264                         return 2;
265
266                 return res == 15 ? 0 : 3;
267         }
268
269         /*
270          * Test custom marshaller class not implementing ICustomMarshaler
271          */
272
273         public class Marshal2 {
274         }
275
276         [DllImport ("libtest")]
277         private static extern IntPtr mono_test_marshal_pass_return_custom2 (int i,  
278                                                                                                                                         [MarshalAs( UnmanagedType.CustomMarshaler, MarshalTypeRef = typeof (Marshal3), MarshalCookie = "5")] object number, int j);
279
280         public static int test_0_not_icustommarshaller () {
281                 try {
282                         mono_test_marshal_pass_return_custom2 (5, 10, 5);
283                 }
284                 catch (ApplicationException) {
285                         return 0;
286                 }
287                 return 1;
288         }
289
290
291         /*
292          * Test custom marshaller class missing GetInstance method
293          */
294
295         public class Marshal3 : ICustomMarshaler {
296                 public void CleanUpManagedData (object managedObj)
297                 {
298                 }
299
300                 public void CleanUpNativeData (IntPtr pNativeData)
301                 {
302                 }
303
304                 public int GetNativeDataSize ()
305                 {
306                         return 4;
307                 }
308
309                 public IntPtr MarshalManagedToNative (object managedObj)
310                 {
311                         return IntPtr.Zero;
312                 }
313
314                 public object MarshalNativeToManaged (IntPtr pNativeData)
315                 {
316                         return null;
317                 }
318         }
319
320         public class Marshal4 : Marshal3 {
321                 public static object GetInstance (string s) {
322                         return null;
323                 }
324         }
325
326         public class Marshal5 : Marshal3 {
327                 public static ICustomMarshaler GetInstance (object s) {
328                         return null;
329                 }
330         }
331
332         [DllImport ("libtest", EntryPoint = "mono_test_marshal_pass_return_custom2")]
333         private static extern IntPtr mono_test_marshal_pass_return_custom3 (int i,  
334                                                                                                                                         [MarshalAs( UnmanagedType.CustomMarshaler, MarshalTypeRef = typeof (Marshal3), MarshalCookie = "5")] object number, int j);
335
336         [DllImport ("libtest", EntryPoint = "mono_test_marshal_pass_return_custom2")]
337         private static extern IntPtr mono_test_marshal_pass_return_custom4 (int i,  
338                                                                                                                                         [MarshalAs( UnmanagedType.CustomMarshaler, MarshalTypeRef = typeof (Marshal4), MarshalCookie = "5")] object number, int j);
339
340         [DllImport ("libtest", EntryPoint = "mono_test_marshal_pass_return_custom2")]
341         private static extern IntPtr mono_test_marshal_pass_return_custom5 (int i,  
342                                                                                                                                         [MarshalAs( UnmanagedType.CustomMarshaler, MarshalTypeRef = typeof (Marshal5), MarshalCookie = "5")] object number, int j);
343
344         public static int test_0_missing_getinstance1 () {
345                 try {
346                         mono_test_marshal_pass_return_custom3 (5, 10, 5);
347                 }
348                 catch (ApplicationException) {
349                         return 0;
350                 }
351                 return 1;
352         }
353
354         public static int test_0_missing_getinstance2 () {
355                 try {
356                         mono_test_marshal_pass_return_custom4 (5, 10, 5);
357                 }
358                 catch (ApplicationException) {
359                         return 0;
360                 }
361                 return 1;
362         }
363
364         public static int test_0_missing_getinstance3 () {
365                 try {
366                         mono_test_marshal_pass_return_custom5 (5, 10, 5);
367                 }
368                 catch (ApplicationException) {
369                         return 0;
370                 }
371                 return 1;
372         }
373
374 }