2 // marshal9.cs: tests for custom marshalling
6 using System
.Runtime
.InteropServices
;
8 [AttributeUsage (AttributeTargets
.Method
)]
9 sealed class MonoPInvokeCallbackAttribute
: Attribute
{
10 public MonoPInvokeCallbackAttribute (Type t
) {}
13 public class Marshal1
: ICustomMarshaler
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
) {
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
);
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
53 public int GetNativeDataSize ()
55 //Console.WriteLine("GetNativeDataSize() called");
59 public IntPtr
MarshalManagedToNative (object managedObj
)
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);
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
;
84 public static int Main (string[] args
) {
85 return TestDriver
.RunTests (typeof (Tests
));
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)
105 if (Marshal1
.cleanup_native_count
!= 2)
107 if (Marshal1
.native_to_managed_count
!= 1)
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;
123 int res
= mono_test_marshal_pass_out_custom (5, out o
, 5);
129 if (Marshal1
.cleanup_managed_count
!= 0)
131 if (Marshal1
.cleanup_native_count
!= 1)
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)
152 if (Marshal1
.cleanup_managed_count
!= 0)
154 if (Marshal1
.cleanup_native_count
!= 1)
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);
175 if (Marshal1
.native_to_managed_result
!= null)
178 if (Marshal1
.cleanup_managed_count
!= 0)
180 if (Marshal1
.cleanup_native_count
!= 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;
196 int res
= mono_test_marshal_pass_byref_custom (5, ref o
, 5);
202 if (Marshal1
.cleanup_managed_count
!= 0)
204 if (Marshal1
.cleanup_native_count
!= 1)
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)
225 if (Marshal1
.cleanup_native_count
!= 0)
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
) {
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)
259 if (Marshal1
.cleanup_native_count
!= 0)
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)
274 if (Marshal1
.cleanup_native_count
!= 0)
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 () {
293 mono_test_marshal_pass_return_custom2 (5, 10, 5);
295 catch (ApplicationException
) {
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 ()
320 public IntPtr
MarshalManagedToNative (object managedObj
)
325 public object MarshalNativeToManaged (IntPtr pNativeData
)
331 public class Marshal4
: Marshal3
{
332 public static object GetInstance (string s
) {
337 public class Marshal5
: Marshal3
{
338 public static ICustomMarshaler
GetInstance (object s
) {
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 () {
357 mono_test_marshal_pass_return_custom3 (5, 10, 5);
359 catch (ApplicationException
) {
365 public static int test_0_missing_getinstance2 () {
367 mono_test_marshal_pass_return_custom4 (5, 10, 5);
369 catch (ApplicationException
) {
375 public static int test_0_missing_getinstance3 () {
377 mono_test_marshal_pass_return_custom5 (5, 10, 5);
379 catch (ApplicationException
) {
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 ()
407 public IntPtr
MarshalManagedToNative (object managedObj
)
409 managed_to_native_count
++;
413 public object MarshalNativeToManaged (IntPtr pNativeData
)
415 native_to_managed_count
++;
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)
436 if (Marshal6
.native_to_managed_count
!= 0)
442 [MonoPInvokeCallback (typeof (custom_out_param_delegate
))]
443 private static void custom_out_param (out object i
)