[2020-02] Avoid following invalid pointers in mono_w32process_get_modules on Darwin...
[mono-project.git] / mono / tests / marshal9.cs
blobf19059435939a60dfc0eafec50e2c05d152b8594
1 //
2 // marshal9.cs: tests for custom marshalling
3 //
5 using System;
6 using System.Runtime.InteropServices;
8 [AttributeUsage (AttributeTargets.Method)]
9 sealed class MonoPInvokeCallbackAttribute : Attribute {
10 public MonoPInvokeCallbackAttribute (Type t) {}
13 public class Marshal1 : ICustomMarshaler
15 int param;
17 public static int cleanup_managed_count = 0;
19 public static int cleanup_native_count = 0;
21 public static int native_to_managed_count = 0;
23 public static object native_to_managed_result = null;
25 public Marshal1 (int param) {
26 this.param = param;
29 public static ICustomMarshaler GetInstance (string s) {
30 int param = Int32.Parse (s);
31 return new Marshal1 (param);
34 public void CleanUpManagedData (object managedObj)
36 //Console.WriteLine ("CleanUpManagedData called");
37 cleanup_managed_count ++;
40 public void CleanUpNativeData (IntPtr pNativeData)
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 ++;
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 ()
55 //Console.WriteLine("GetNativeDataSize() called");
56 return 4;
59 public IntPtr MarshalManagedToNative (object managedObj)
61 int number;
62 IntPtr ptr;
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);
69 //Console.WriteLine ("ToNative: " + ptr);
70 return ptr;
73 public object MarshalNativeToManaged (IntPtr pNativeData)
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;
82 public class Tests
84 public static int Main (string[] args) {
85 return TestDriver.RunTests (typeof (Tests));
86 return 0;
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);
95 public static int test_0_pass_return () {
97 Marshal1.cleanup_managed_count = 0;
98 Marshal1.cleanup_native_count = 0;
99 Marshal1.native_to_managed_count = 0;
101 int res = (int)mono_test_marshal_pass_return_custom (5, 10, 5);
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;
110 return res == 15 ? 0 : 3;
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);
117 public static int test_0_pass_out () {
119 Marshal1.cleanup_managed_count = 0;
120 Marshal1.cleanup_native_count = 0;
122 object o = 0;
123 int res = mono_test_marshal_pass_out_custom (5, out o, 5);
125 /* 10 + 5 + 5 + 5 */
126 if ((int)o != 25)
127 return 1;
129 if (Marshal1.cleanup_managed_count != 0)
130 return 2;
131 if (Marshal1.cleanup_native_count != 1)
132 return 3;
134 return 0;
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);
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;
146 int res = mono_test_marshal_pass_inout_custom (5, 5, 5);
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;
152 if (Marshal1.cleanup_managed_count != 0)
153 return 2;
154 if (Marshal1.cleanup_native_count != 1)
155 return 3;
157 return 0;
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);
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;
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);
172 if (res != 0)
173 return 1;
175 if (Marshal1.native_to_managed_result != null)
176 return 2;
178 if (Marshal1.cleanup_managed_count != 0)
179 return 3;
180 if (Marshal1.cleanup_native_count != 0)
181 return 4;
183 return 0;
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);
190 public static int test_0_pass_ref () {
192 Marshal1.cleanup_managed_count = 0;
193 Marshal1.cleanup_native_count = 0;
195 object o = 10;
196 int res = mono_test_marshal_pass_byref_custom (5, ref o, 5);
198 /* 10 + 5 + 5 + 5 */
199 if ((int)o != 25)
200 return 1;
202 if (Marshal1.cleanup_managed_count != 0)
203 return 2;
204 if (Marshal1.cleanup_native_count != 1)
205 return 3;
207 return 0;
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);
216 public static int test_0_pass_return_null () {
218 Marshal1.cleanup_managed_count = 0;
219 Marshal1.cleanup_native_count = 0;
221 object o = mono_test_marshal_pass_return_custom_null (5, null, 5);
223 if (Marshal1.cleanup_managed_count != 0)
224 return 1;
225 if (Marshal1.cleanup_native_count != 0)
226 return 2;
228 return (o == null) ? 0 : 1;
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);
234 [DllImport ("libtest")]
235 private static extern int mono_test_marshal_pass_return_custom_in_delegate (pass_return_int_delegate del);
237 [DllImport ("libtest")]
238 private static extern int mono_test_marshal_pass_return_custom_null_in_delegate (pass_return_int_delegate del);
240 [MonoPInvokeCallback (typeof (pass_return_int_delegate))]
241 private static object pass_return_int (object i) {
242 return (int)i;
245 [MonoPInvokeCallback (typeof (pass_return_int_delegate))]
246 private static object pass_return_null (object i) {
247 return (i == null) ? null : new Object ();
250 public static int test_0_pass_return_delegate () {
252 Marshal1.cleanup_managed_count = 0;
253 Marshal1.cleanup_native_count = 0;
255 int res = mono_test_marshal_pass_return_custom_in_delegate (new pass_return_int_delegate (pass_return_int));
257 if (Marshal1.cleanup_managed_count != 2)
258 return 1;
259 if (Marshal1.cleanup_native_count != 0)
260 return 2;
262 return res == 15 ? 0 : 3;
265 public static int test_0_pass_return_null_delegate () {
267 Marshal1.cleanup_managed_count = 0;
268 Marshal1.cleanup_native_count = 0;
270 int res = mono_test_marshal_pass_return_custom_null_in_delegate (new pass_return_int_delegate (pass_return_null));
272 if (Marshal1.cleanup_managed_count != 0)
273 return 1;
274 if (Marshal1.cleanup_native_count != 0)
275 return 2;
277 return res == 15 ? 0 : 3;
281 * Test custom marshaller class not implementing ICustomMarshaler
284 public class Marshal2 {
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);
291 public static int test_0_not_icustommarshaller () {
292 try {
293 mono_test_marshal_pass_return_custom2 (5, 10, 5);
295 catch (ApplicationException) {
296 return 0;
298 return 1;
303 * Test custom marshaller class missing GetInstance method
306 public class Marshal3 : ICustomMarshaler {
307 public void CleanUpManagedData (object managedObj)
311 public void CleanUpNativeData (IntPtr pNativeData)
315 public int GetNativeDataSize ()
317 return 4;
320 public IntPtr MarshalManagedToNative (object managedObj)
322 return IntPtr.Zero;
325 public object MarshalNativeToManaged (IntPtr pNativeData)
327 return null;
331 public class Marshal4 : Marshal3 {
332 public static object GetInstance (string s) {
333 return null;
337 public class Marshal5 : Marshal3 {
338 public static ICustomMarshaler GetInstance (object s) {
339 return null;
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);
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);
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);
355 public static int test_0_missing_getinstance1 () {
356 try {
357 mono_test_marshal_pass_return_custom3 (5, 10, 5);
359 catch (ApplicationException) {
360 return 0;
362 return 1;
365 public static int test_0_missing_getinstance2 () {
366 try {
367 mono_test_marshal_pass_return_custom4 (5, 10, 5);
369 catch (ApplicationException) {
370 return 0;
372 return 1;
375 public static int test_0_missing_getinstance3 () {
376 try {
377 mono_test_marshal_pass_return_custom5 (5, 10, 5);
379 catch (ApplicationException) {
380 return 0;
382 return 1;
385 public class Marshal6 : ICustomMarshaler {
386 public static int managed_to_native_count = 0;
387 public static int native_to_managed_count = 0;
389 public static ICustomMarshaler GetInstance (string s)
391 return new Marshal6 ();
394 public void CleanUpManagedData (object managedObj)
398 public void CleanUpNativeData (IntPtr pNativeData)
402 public int GetNativeDataSize ()
404 return 4;
407 public IntPtr MarshalManagedToNative (object managedObj)
409 managed_to_native_count++;
410 return IntPtr.Zero;
413 public object MarshalNativeToManaged (IntPtr pNativeData)
415 native_to_managed_count++;
416 return null;
420 public delegate void custom_out_param_delegate ([MarshalAs (UnmanagedType.CustomMarshaler, MarshalTypeRef = typeof (Marshal6), MarshalCookie = "5")] out object o);
422 [DllImport ("libtest")]
423 private static extern int mono_test_marshal_custom_out_param_delegate (custom_out_param_delegate del);
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 ()
429 Marshal6.managed_to_native_count = 0;
430 Marshal6.native_to_managed_count = 0;
432 int res = mono_test_marshal_custom_out_param_delegate (new custom_out_param_delegate (custom_out_param));
434 if (Marshal6.managed_to_native_count != 1)
435 return 1;
436 if (Marshal6.native_to_managed_count != 0)
437 return 2;
439 return 0;
442 [MonoPInvokeCallback (typeof (custom_out_param_delegate))]
443 private static void custom_out_param (out object i)
445 i = new object();