@@ -30,6 +30,7 @@ public CSharpMarshalContext(Driver driver)
3030
3131        public  TextGenerator  ArgumentPrefix  {  get ;  private  set ;  } 
3232        public  TextGenerator  Cleanup  {  get ;  private  set ;  } 
33+         public  bool  HasFixedBlock  {  get ;  set ;  } 
3334    } 
3435
3536    public  abstract  class  CSharpMarshalPrinter  :  MarshalPrinter 
@@ -390,28 +391,43 @@ public override bool VisitArrayType(ArrayType array, TypeQualifiers quals)
390391            if  ( ! VisitType ( array ,  quals ) ) 
391392                return  false ; 
392393
393-             Class  @class ; 
394394            switch  ( array . SizeType ) 
395395            { 
396396                case  ArrayType . ArraySize . Constant : 
397-                     var  supportBefore  =  Context . SupportBefore ; 
398-                     supportBefore . WriteLine ( "if ({0} != null)" ,  Context . ArgName ) ; 
399-                     supportBefore . WriteStartBraceIndent ( ) ; 
400-                     if  ( array . Type . Desugar ( ) . TryGetClass ( out  @class )  &&  @class . IsRefType ) 
397+                     if  ( string . IsNullOrEmpty ( Context . ReturnVarName ) ) 
401398                    { 
402-                         supportBefore . WriteLine ( "if (value.Length != {0})" ,  array . Size ) ; 
403-                         supportBefore . WriteLineIndent ( "throw new ArgumentOutOfRangeException(\" {0}\" , \" The provided array's dimensions doesn't match the required size.\" );" , 
404-                             Context . Parameter . Name ) ; 
399+                         Context . SupportBefore . WriteLine ( "if ({0} == null || {0}.Length != {1})" ,  Context . Parameter . Name ,  array . Size ) ; 
400+                         ThrowArgumentOutOfRangeException ( ) ; 
401+                         const  string  ptr  =  "__ptr" ; 
402+                         Context . SupportBefore . WriteLine ( "fixed ({0}* {1} = {2})" ,  array . Type ,  ptr ,  Context . Parameter . Name ) ; 
403+                         Context . SupportBefore . WriteStartBraceIndent ( ) ; 
404+                         Context . Return . Write ( "new global::System.IntPtr({0})" ,  ptr ) ; 
405+                         CSharpContext . HasFixedBlock  =  true ; 
405406                    } 
406-                     supportBefore . WriteLine ( "for (int i = 0; i < {0}; i++)" ,  array . Size ) ; 
407-                     if  ( @class  !=  null  &&  @class . IsRefType ) 
408-                         supportBefore . WriteLineIndent ( "{0}[i * sizeof({2}.Internal)] = *((byte*)({2}.Internal*){1}[i].__Instance);" , 
409-                             Context . ReturnVarName ,  Context . ArgName ,  array . Type ) ; 
410407                    else 
411-                         supportBefore . WriteLineIndent ( "{0}[i] = {1}[i]{2};" , 
412-                             Context . ReturnVarName ,  Context . ArgName , 
413-                             array . Type . IsPointerToPrimitiveType ( PrimitiveType . Void )  ?  ".ToPointer()"  :  string . Empty ) ; 
414-                     supportBefore . WriteCloseBraceIndent ( ) ; 
408+                     { 
409+                         var  supportBefore  =  Context . SupportBefore ; 
410+                         supportBefore . WriteLine ( "if ({0} != null)" ,  Context . ArgName ) ; 
411+                         supportBefore . WriteStartBraceIndent ( ) ; 
412+                         Class  @class ; 
413+                         if  ( array . Type . Desugar ( ) . TryGetClass ( out  @class )  &&  @class . IsRefType ) 
414+                         { 
415+                             supportBefore . WriteLine ( "if (value.Length != {0})" ,  array . Size ) ; 
416+                             ThrowArgumentOutOfRangeException ( ) ; 
417+                         } 
418+                         supportBefore . WriteLine ( "for (int i = 0; i < {0}; i++)" ,  array . Size ) ; 
419+                         if  ( @class  !=  null  &&  @class . IsRefType ) 
420+                             supportBefore . WriteLineIndent ( 
421+                                 "{0}[i * sizeof({2}.Internal)] = *((byte*)({2}.Internal*){1}[i].__Instance);" , 
422+                                 Context . ReturnVarName ,  Context . ArgName ,  array . Type ) ; 
423+                         else 
424+                             supportBefore . WriteLineIndent ( "{0}[i] = {1}[i]{2};" , 
425+                                 Context . ReturnVarName ,  Context . ArgName , 
426+                                 array . Type . IsPointerToPrimitiveType ( PrimitiveType . Void ) 
427+                                     ?  ".ToPointer()" 
428+                                     :  string . Empty ) ; 
429+                         supportBefore . WriteCloseBraceIndent ( ) ; 
430+                     } 
415431                    break ; 
416432                default : 
417433                    Context . Return . Write ( "null" ) ; 
@@ -420,6 +436,14 @@ public override bool VisitArrayType(ArrayType array, TypeQualifiers quals)
420436            return  true ; 
421437        } 
422438
439+         private  void  ThrowArgumentOutOfRangeException ( ) 
440+         { 
441+             Context . SupportBefore . WriteLineIndent ( 
442+                 "throw new ArgumentOutOfRangeException(\" {0}\" , "  + 
443+                 "\" The dimensions of the provided array don't match the required size.\" );" , 
444+                 Context . Parameter . Name ) ; 
445+         } 
446+ 
423447        public  bool  VisitDelegateType ( FunctionType  function ,  string  type ) 
424448        { 
425449            Context . Return . Write ( "{0} == null ? global::System.IntPtr.Zero : Marshal.GetFunctionPointerForDelegate({0})" , 
@@ -432,6 +456,17 @@ public override bool VisitPointerType(PointerType pointer, TypeQualifiers quals)
432456            if  ( ! VisitType ( pointer ,  quals ) ) 
433457                return  false ; 
434458
459+             if  ( Context . Function  !=  null  &&  pointer . IsPrimitiveTypeConvertibleToRef ( ) ) 
460+             { 
461+                 string  refParamPtr  =  string . Format ( "__refParamPtr{0}" ,  Context . ParameterIndex ) ; 
462+                 Context . SupportBefore . WriteLine ( "fixed ({0} {1} = &{2})" , 
463+                     pointer ,  refParamPtr ,  Context . Parameter . Name ) ; 
464+                 CSharpContext . HasFixedBlock  =  true ; 
465+                 Context . SupportBefore . WriteStartBraceIndent ( ) ; 
466+                 Context . Return . Write ( refParamPtr ) ; 
467+                 return  true ; 
468+             } 
469+ 
435470            var  param  =  Context . Parameter ; 
436471            var  isRefParam  =  param  !=  null  &&  ( param . IsInOut  ||  param . IsOut ) ; 
437472
0 commit comments