@@ -30,6 +30,7 @@ public CSharpMarshalContext(Driver driver)
30
30
31
31
public TextGenerator ArgumentPrefix { get ; private set ; }
32
32
public TextGenerator Cleanup { get ; private set ; }
33
+ public bool HasFixedBlock { get ; set ; }
33
34
}
34
35
35
36
public abstract class CSharpMarshalPrinter : MarshalPrinter
@@ -390,28 +391,44 @@ public override bool VisitArrayType(ArrayType array, TypeQualifiers quals)
390
391
if ( ! VisitType ( array , quals ) )
391
392
return false ;
392
393
393
- Class @class ;
394
394
switch ( array . SizeType )
395
395
{
396
396
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 ) )
401
398
{
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
+ const string ptr = "__ptr" ;
400
+ Context . SupportBefore . WriteLine ( "fixed ({0}* {1} = {2})" , array . Type , ptr , Context . Parameter . Name ) ;
401
+ Context . SupportBefore . WriteStartBraceIndent ( ) ;
402
+ Context . Return . Write ( "new global::System.IntPtr({0})" , ptr ) ;
403
+ CSharpContext . HasFixedBlock = true ;
405
404
}
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 ) ;
410
405
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 ( ) ;
406
+ {
407
+ var supportBefore = Context . SupportBefore ;
408
+ supportBefore . WriteLine ( "if ({0} != null)" , Context . ArgName ) ;
409
+ supportBefore . WriteStartBraceIndent ( ) ;
410
+ Class @class ;
411
+ if ( array . Type . Desugar ( ) . TryGetClass ( out @class ) && @class . IsRefType )
412
+ {
413
+ supportBefore . WriteLine ( "if (value.Length != {0})" , array . Size ) ;
414
+ supportBefore . WriteLineIndent (
415
+ "throw new ArgumentOutOfRangeException(\" {0}\" ," +
416
+ "\" The provided array's dimensions doesn't match the required size.\" );" ,
417
+ Context . Parameter . Name ) ;
418
+ }
419
+ supportBefore . WriteLine ( "for (int i = 0; i < {0}; i++)" , array . Size ) ;
420
+ if ( @class != null && @class . IsRefType )
421
+ supportBefore . WriteLineIndent (
422
+ "{0}[i * sizeof({2}.Internal)] = *((byte*)({2}.Internal*){1}[i].__Instance);" ,
423
+ Context . ReturnVarName , Context . ArgName , array . Type ) ;
424
+ else
425
+ supportBefore . WriteLineIndent ( "{0}[i] = {1}[i]{2};" ,
426
+ Context . ReturnVarName , Context . ArgName ,
427
+ array . Type . IsPointerToPrimitiveType ( PrimitiveType . Void )
428
+ ? ".ToPointer()"
429
+ : string . Empty ) ;
430
+ supportBefore . WriteCloseBraceIndent ( ) ;
431
+ }
415
432
break ;
416
433
default :
417
434
Context . Return . Write ( "null" ) ;
@@ -432,6 +449,17 @@ public override bool VisitPointerType(PointerType pointer, TypeQualifiers quals)
432
449
if ( ! VisitType ( pointer , quals ) )
433
450
return false ;
434
451
452
+ if ( Context . Function != null && pointer . IsPrimitiveTypeConvertibleToRef ( ) )
453
+ {
454
+ string refParamPtr = string . Format ( "__refParamPtr{0}" , Context . ParameterIndex ) ;
455
+ Context . SupportBefore . WriteLine ( "fixed ({0} {1} = &{2})" ,
456
+ pointer , refParamPtr , Context . Parameter . Name ) ;
457
+ CSharpContext . HasFixedBlock = true ;
458
+ Context . SupportBefore . WriteStartBraceIndent ( ) ;
459
+ Context . Return . Write ( refParamPtr ) ;
460
+ return true ;
461
+ }
462
+
435
463
var param = Context . Parameter ;
436
464
var isRefParam = param != null && ( param . IsInOut || param . IsOut ) ;
437
465
0 commit comments