using System;
using System.Runtime.InteropServices;
+[AttributeUsage (AttributeTargets.Method)]
+sealed class MonoPInvokeCallbackAttribute : Attribute {
+ public MonoPInvokeCallbackAttribute (Type t) {}
+}
+
public class Marshal1 : ICustomMarshaler
{
int param;
public static int cleanup_native_count = 0;
+ public static int native_to_managed_count = 0;
+
+ public static object native_to_managed_result = null;
+
public Marshal1 (int param) {
this.param = param;
}
}
// I really do not understand the purpose of this method
- // or went it would be called. In fact, Rotor never seems
+ // or when it would be called. In fact, Rotor never seems
// to call it.
public int GetNativeDataSize ()
{
public object MarshalNativeToManaged (IntPtr pNativeData)
{
//Console.WriteLine ("ToManaged: " + pNativeData);
- return param + Marshal.ReadInt32 (new IntPtr (pNativeData.ToInt64 () + 4));
+ native_to_managed_count ++;
+ native_to_managed_result = param + Marshal.ReadInt32 (new IntPtr (pNativeData.ToInt64 () + 4));
+ return native_to_managed_result;
}
}
{
public static int Main (string[] args) {
return TestDriver.RunTests (typeof (Tests));
+ return 0;
}
[DllImport ("libtest")]
Marshal1.cleanup_managed_count = 0;
Marshal1.cleanup_native_count = 0;
+ Marshal1.native_to_managed_count = 0;
int res = (int)mono_test_marshal_pass_return_custom (5, 10, 5);
return 1;
if (Marshal1.cleanup_native_count != 2)
return 2;
+ if (Marshal1.native_to_managed_count != 1)
+ return 3;
return res == 15 ? 0 : 3;
}
return 0;
}
+ [DllImport ("libtest")]
+ private static extern int mono_test_marshal_pass_inout_custom (int i,
+ [MarshalAs( UnmanagedType.CustomMarshaler, MarshalTypeRef = typeof (Marshal1), MarshalCookie = "5"), In, Out] object number, int j);
+
+ public static int test_0_pass_inout () {
+ Marshal1.cleanup_managed_count = 0;
+ Marshal1.cleanup_native_count = 0;
+ Marshal1.native_to_managed_result = null;
+
+ int res = mono_test_marshal_pass_inout_custom (5, 5, 5);
+
+ // The changes made by the [Out] custom marshaller are not visible to the caller
+ if ((int)Marshal1.native_to_managed_result != 20)
+ return 1;
+
+ if (Marshal1.cleanup_managed_count != 0)
+ return 2;
+ if (Marshal1.cleanup_native_count != 1)
+ return 3;
+
+ return 0;
+ }
+
+ [DllImport ("libtest")]
+ private static extern int mono_test_marshal_pass_out_byval_custom (int i,
+ [MarshalAs( UnmanagedType.CustomMarshaler, MarshalTypeRef = typeof (Marshal1), MarshalCookie = "5"), Out] object number, int j);
+
+ public static int test_0_pass_out_byval () {
+ Marshal1.cleanup_managed_count = 0;
+ Marshal1.cleanup_native_count = 0;
+ Marshal1.native_to_managed_result = null;
+
+ // MS.NET passes NULL and does no marshalling in this case
+ int res = mono_test_marshal_pass_out_byval_custom (5, 5, 5);
+
+ if (res != 0)
+ return 1;
+
+ if (Marshal1.native_to_managed_result != null)
+ return 2;
+
+ if (Marshal1.cleanup_managed_count != 0)
+ return 3;
+ if (Marshal1.cleanup_native_count != 0)
+ return 4;
+
+ return 0;
+ }
[DllImport ("libtest")]
private static extern int mono_test_marshal_pass_byref_custom (int i,
[DllImport ("libtest")]
private static extern int mono_test_marshal_pass_return_custom_null_in_delegate (pass_return_int_delegate del);
+ [MonoPInvokeCallback (typeof (pass_return_int_delegate))]
private static object pass_return_int (object i) {
return (int)i;
}
+ [MonoPInvokeCallback (typeof (pass_return_int_delegate))]
private static object pass_return_null (object i) {
return (i == null) ? null : new Object ();
}
return 1;
}
+ public class Marshal6 : ICustomMarshaler {
+ public static int managed_to_native_count = 0;
+ public static int native_to_managed_count = 0;
+
+ public static ICustomMarshaler GetInstance (string s)
+ {
+ return new Marshal6 ();
+ }
+
+ public void CleanUpManagedData (object managedObj)
+ {
+ }
+
+ public void CleanUpNativeData (IntPtr pNativeData)
+ {
+ }
+
+ public int GetNativeDataSize ()
+ {
+ return 4;
+ }
+
+ public IntPtr MarshalManagedToNative (object managedObj)
+ {
+ managed_to_native_count++;
+ return IntPtr.Zero;
+ }
+
+ public object MarshalNativeToManaged (IntPtr pNativeData)
+ {
+ native_to_managed_count++;
+ return null;
+ }
+ }
+
+ public delegate void custom_out_param_delegate ([MarshalAs (UnmanagedType.CustomMarshaler, MarshalTypeRef = typeof (Marshal6), MarshalCookie = "5")] out object o);
+
+ [DllImport ("libtest")]
+ private static extern int mono_test_marshal_custom_out_param_delegate (custom_out_param_delegate del);
+
+ // ICustomMarshaler.MarshalNativeToManaged should not be called when the
+ // parameter is marked as an out.
+ public static int test_0_native_to_managed_custom_parameter ()
+ {
+ Marshal6.managed_to_native_count = 0;
+ Marshal6.native_to_managed_count = 0;
+
+ int res = mono_test_marshal_custom_out_param_delegate (new custom_out_param_delegate (custom_out_param));
+
+ if (Marshal6.managed_to_native_count != 1)
+ return 1;
+ if (Marshal6.native_to_managed_count != 0)
+ return 2;
+
+ return 0;
+ }
+
+ [MonoPInvokeCallback (typeof (custom_out_param_delegate))]
+ private static void custom_out_param (out object i)
+ {
+ i = new object();
+ }
+
}