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