@@ -164,6 +164,37 @@ public static void Parameter_CustomMarshalerProvided_CallsMethodsInCorrectOrderi
164164 "Called CleanUpNativeData"
165165 } ) ;
166166 Assert . Equal ( expectedOrderingSecondCall , OrderTrackingCustomMarshaler . Events ) ;
167+
168+ // GetInstance is only called once.
169+ string val3 = "7488" ;
170+ Assert . Equal ( val3 , OrderTrackingMethodRef ( ref val3 ) ) ;
171+ IEnumerable < string > expectedOrderingThirdCall = expectedOrderingSecondCall . Concat ( new string [ ]
172+ {
173+ "Called MarshalManagedToNative" ,
174+ "Called MarshalNativeToManaged" ,
175+ "Called CleanUpManagedData" ,
176+ "Called MarshalNativeToManaged" ,
177+ "Called CleanUpNativeData" ,
178+ } ) ;
179+ Assert . Equal ( expectedOrderingThirdCall . Skip ( 7 ) , OrderTrackingCustomMarshaler . Events . Skip ( 7 ) ) ;
180+
181+ OrderTrackingMethodOut ( out var val4 ) ;
182+ Assert . Equal ( "2334" , val4 ) ;
183+ IEnumerable < string > expectedOrderingForthCall = expectedOrderingThirdCall . Concat ( new string [ ]
184+ {
185+ "Called MarshalNativeToManaged" ,
186+ } ) ;
187+ Assert . Equal ( expectedOrderingForthCall . Skip ( 12 ) , OrderTrackingCustomMarshaler . Events . Skip ( 12 ) ) ;
188+
189+ var val5 = OrderTrackingMethodDelegate ( 439 , ( x ) => x . ToString ( ) ) ;
190+ Assert . Equal ( "439" , val5 ) ;
191+ IEnumerable < string > expectedOrderingFifthCall = expectedOrderingForthCall . Concat ( new string [ ]
192+ {
193+ "Called MarshalManagedToNative" ,
194+ "Called CleanUpManagedData" ,
195+ "Called MarshalNativeToManaged" ,
196+ } ) ;
197+ Assert . Equal ( expectedOrderingFifthCall . Skip ( 13 ) , OrderTrackingCustomMarshaler . Events . Skip ( 13 ) ) ;
167198 }
168199
169200 // This should only be used *once*, as it uses static state.
@@ -201,7 +232,7 @@ public IntPtr MarshalManagedToNative(object ManagedObj)
201232 public object MarshalNativeToManaged ( IntPtr pNativeData )
202233 {
203234 Events . Add ( "Called MarshalNativeToManaged" ) ;
204- return pNativeData . ToInt32 ( ) . ToString ( ) ;
235+ return pNativeData . ToInt64 ( ) . ToString ( ) ;
205236 }
206237
207238 public static ICustomMarshaler GetInstance ( string cookie )
@@ -216,6 +247,20 @@ public static ICustomMarshaler GetInstance(string cookie)
216247 [ return : MarshalAs ( UnmanagedType . CustomMarshaler , MarshalTypeRef = typeof ( OrderTrackingCustomMarshaler ) ) ]
217248 public static extern string OrderTrackingMethod ( [ MarshalAs ( UnmanagedType . CustomMarshaler , MarshalTypeRef = typeof ( OrderTrackingCustomMarshaler ) ) ] string str ) ;
218249
250+ [ DllImport ( "CustomMarshalersPrimitives" , EntryPoint = "NativeParseIntRef" ) ]
251+ [ return : MarshalAs ( UnmanagedType . CustomMarshaler , MarshalTypeRef = typeof ( OrderTrackingCustomMarshaler ) ) ]
252+ public static extern string OrderTrackingMethodRef ( [ MarshalAs ( UnmanagedType . CustomMarshaler , MarshalTypeRef = typeof ( OrderTrackingCustomMarshaler ) ) ] ref string str ) ;
253+
254+ [ DllImport ( "CustomMarshalersPrimitives" , EntryPoint = "NativeParseIntOut" ) ]
255+ public static extern void OrderTrackingMethodOut ( [ MarshalAs ( UnmanagedType . CustomMarshaler , MarshalTypeRef = typeof ( OrderTrackingCustomMarshaler ) ) ] out string str ) ;
256+
257+ [ return : MarshalAs ( UnmanagedType . CustomMarshaler , MarshalTypeRef = typeof ( OrderTrackingCustomMarshaler ) ) ]
258+ public delegate string TestDelegate ( int val ) ;
259+
260+ [ DllImport ( "CustomMarshalersPrimitives" , EntryPoint = "NativeParseIntDelegate" ) ]
261+ [ return : MarshalAs ( UnmanagedType . CustomMarshaler , MarshalTypeRef = typeof ( OrderTrackingCustomMarshaler ) ) ]
262+ public static extern string OrderTrackingMethodDelegate ( int val , TestDelegate dlg ) ;
263+
219264 public static void CustomMarshaler_BothMarshalTypeRefAndMarshalTypeProvided_PicksMarshalType ( )
220265 {
221266 Assert . Equal ( 2 , BothTypeRefAndTypeMethod ( "64001" ) ) ;
@@ -613,6 +658,17 @@ public void CleanUpManagedData(object ManagedObj) { }
613658 [ DllImport ( LibcLibrary , EntryPoint = "atoi" , CallingConvention = CallingConvention . Cdecl ) ]
614659 public static extern int DifferentCustomMarshalerType ( [ MarshalAs ( UnmanagedType . CustomMarshaler , MarshalTypeRef = typeof ( OuterCustomMarshaler ) ) ] string str ) ;
615660
661+ [ return : MarshalAs ( UnmanagedType . CustomMarshaler , MarshalTypeRef = typeof ( BoxedValueTypeCustomMarshaler ) ) ]
662+ public delegate string TestDelegateRef ( [ MarshalAs ( UnmanagedType . CustomMarshaler , MarshalTypeRef = typeof ( BoxedValueTypeCustomMarshaler ) ) ] ref int val ) ;
663+
664+ [ DllImport ( "CustomMarshalersPrimitives" , EntryPoint = "NativeParseIntDelegateRef" ) ]
665+ [ return : MarshalAs ( UnmanagedType . CustomMarshaler , MarshalTypeRef = typeof ( BoxedValueTypeCustomMarshaler ) ) ]
666+ public static extern string CustomMarshallerWithDelegateRef ( int val , TestDelegateRef dlg ) ;
667+
668+ public static void DelegateParameter_MarshalerOnRefInt_ThrowsMarshalDirectiveException ( )
669+ {
670+ Assert . Throws < MarshalDirectiveException > ( ( ) => CustomMarshallerWithDelegateRef ( 84664 , ( ref int x ) => x . ToString ( ) ) ) ;
671+ }
616672 public static int Main ( String [ ] args )
617673 {
618674 try
@@ -643,6 +699,7 @@ public static int Main(String[] args)
643699 Parameter_CleanUpNativeDataMethodThrows_ThrowsActualException ( ) ;
644700 Field_ParentIsStruct_ThrowsTypeLoadException ( ) ;
645701 Parameter_DifferentCustomMarshalerType_MarshalsCorrectly ( ) ;
702+ DelegateParameter_MarshalerOnRefInt_ThrowsMarshalDirectiveException ( ) ;
646703 }
647704 catch ( Exception e )
648705 {
0 commit comments