@@ -46,8 +46,6 @@ public CSharpMarshalNativeToManagedPrinter(CSharpMarshalContext context)
4646 typePrinter = new CSharpTypePrinter ( context . Context ) ;
4747 }
4848
49- public bool MarshalsParameter { get ; set ; }
50-
5149 public override bool VisitType ( Type type , TypeQualifiers quals )
5250 {
5351 TypeMap typeMap ;
@@ -132,10 +130,11 @@ public override bool VisitArrayType(ArrayType array, TypeQualifiers quals)
132130 // const char* and const char[] are the same so we can use a string
133131 if ( array . Type . Desugar ( ) . IsPrimitiveType ( PrimitiveType . Char ) &&
134132 array . QualifiedType . Qualifiers . IsConst )
135- return VisitPointerType ( new PointerType
136- {
137- QualifiedPointee = array . QualifiedType
138- } , quals ) ;
133+ {
134+ var pointer = new PointerType { QualifiedPointee = array . QualifiedType } ;
135+ Context . ReturnType = new QualifiedType ( pointer ) ;
136+ return this . VisitPointerType ( pointer , quals ) ;
137+ }
139138 MarshalArray ( array ) ;
140139 break ;
141140 case ArrayType . ArraySize . Variable :
@@ -155,79 +154,45 @@ public override bool VisitPointerType(PointerType pointer, TypeQualifiers quals)
155154 var isRefParam = param != null && ( param . IsInOut || param . IsOut ) ;
156155
157156 var pointee = pointer . Pointee . Desugar ( ) ;
158- bool marshalPointeeAsString = pointee . IsConstCharString ( ) && isRefParam ;
157+ var finalPointee = pointer . GetFinalPointee ( ) . Desugar ( ) ;
158+ PrimitiveType primitive ;
159+ if ( ( pointee . IsConstCharString ( ) && isRefParam ) ||
160+ ( ! finalPointee . IsPrimitiveType ( out primitive ) &&
161+ ! finalPointee . IsEnumType ( ) ) )
162+ return pointer . QualifiedPointee . Visit ( this ) ;
159163
160- if ( ( pointer . IsConstCharString ( ) && ! MarshalsParameter ) ||
161- marshalPointeeAsString )
164+ if ( isRefParam )
162165 {
163- Context . Return . Write ( MarshalStringToManaged ( Context . ReturnVarName ,
164- pointer . GetFinalPointee ( ) . Desugar ( ) as BuiltinType ) ) ;
166+ Context . Return . Write ( "_{0}" , param . Name ) ;
165167 return true ;
166168 }
167169
168- var finalPointee = pointer . GetFinalPointee ( ) ;
169- PrimitiveType primitive ;
170- if ( finalPointee . IsPrimitiveType ( out primitive ) || finalPointee . IsEnumType ( ) )
170+ if ( Context . Context . Options . MarshalCharAsManagedChar &&
171+ primitive == PrimitiveType . Char )
172+ Context . Return . Write ( $ "({ pointer } ) ") ;
173+
174+ var type = Context . ReturnType . Type . Desugar (
175+ resolveTemplateSubstitution : false ) ;
176+ if ( Context . Function != null &&
177+ Context . Function . OperatorKind == CXXOperatorKind . Subscript )
171178 {
172- if ( isRefParam )
179+ if ( type . IsPrimitiveType ( primitive ) )
173180 {
174- Context . Return . Write ( "_{0}" , param . Name ) ;
175- return true ;
181+ Context . Return . Write ( "*" ) ;
176182 }
177-
178- if ( Context . Context . Options . MarshalCharAsManagedChar &&
179- primitive == PrimitiveType . Char )
180- Context . Return . Write ( $ "({ pointer } ) ") ;
181-
182- var type = Context . ReturnType . Type . Desugar (
183- resolveTemplateSubstitution : false ) ;
184- if ( Context . Function != null &&
185- Context . Function . OperatorKind == CXXOperatorKind . Subscript )
183+ else
186184 {
187- if ( type . IsPrimitiveType ( primitive ) )
188- {
189- Context . Return . Write ( "*" ) ;
190- }
191- else
192- {
193- var templateParameter = type as TemplateParameterType ;
194- if ( templateParameter != null )
195- Context . Return . Write ( $ "({ templateParameter . Parameter . Name } ) (object) *") ;
196- }
185+ var templateParameter = type as TemplateParameterType ;
186+ if ( templateParameter != null )
187+ Context . Return . Write ( $ "({ templateParameter . Parameter . Name } ) (object) *") ;
197188 }
198-
199- if ( new QualifiedType ( pointer , quals ) . IsConstRefToPrimitive ( ) )
200- Context . Return . Write ( "*" ) ;
201-
202- Context . Return . Write ( Context . ReturnVarName ) ;
203- return true ;
204189 }
205190
206- return pointer . QualifiedPointee . Visit ( this ) ;
207- }
191+ if ( new QualifiedType ( pointer , quals ) . IsConstRefToPrimitive ( ) )
192+ Context . Return . Write ( "*" ) ;
208193
209- private string MarshalStringToManaged ( string varName , BuiltinType type )
210- {
211- var isChar = type . Type == PrimitiveType . Char ;
212- var encoding = isChar ? Encoding . ASCII : Encoding . Unicode ;
213-
214- if ( Equals ( encoding , Encoding . ASCII ) )
215- encoding = Context . Context . Options . Encoding ;
216-
217- if ( Equals ( encoding , Encoding . ASCII ) )
218- return $ "Marshal.PtrToStringAnsi({ varName } )";
219-
220- if ( Equals ( encoding , Encoding . UTF8 ) )
221- return $ "Marshal.PtrToStringUTF8({ varName } )";
222-
223- // If we reach this, we know the string is Unicode.
224- if ( type . Type == PrimitiveType . Char ||
225- Context . Context . TargetInfo . WCharWidth == 16 )
226- return $ "Marshal.PtrToStringUni({ varName } )";
227-
228- // If we reach this, we should have an UTF-32 wide string.
229- const string encodingName = "System.Text.Encoding.UTF32" ;
230- return $ "CppSharp.Runtime.Helpers.MarshalEncodedString({ varName } , { encodingName } )";
194+ Context . Return . Write ( Context . ReturnVarName ) ;
195+ return true ;
231196 }
232197
233198 public override bool VisitPrimitiveType ( PrimitiveType primitive , TypeQualifiers quals )
@@ -377,11 +342,11 @@ private string HandleReturnedPointer(Class @class, string qualifiedClass)
377342 if ( dtor != null && dtor . IsVirtual )
378343 {
379344 Context . Before . WriteLine ( "else {0}{1} = ({2}) {3}.{4}({5}{6});" ,
380- MarshalsParameter
345+ Context . Parameter != null
381346 ? string . Empty
382347 : string . Format ( "{0}.NativeToManagedMap[{1}] = " , qualifiedClass , Context . ReturnVarName ) ,
383348 ret , qualifiedIdentifier , qualifiedClass , Helpers . CreateInstanceIdentifier , Context . ReturnVarName ,
384- MarshalsParameter ? ", skipVTables: true" : string . Empty ) ;
349+ Context . Parameter != null ? ", skipVTables: true" : string . Empty ) ;
385350 }
386351 else
387352 {
@@ -554,7 +519,6 @@ public override bool VisitPointerType(PointerType pointer, TypeQualifiers quals)
554519 if ( templateSubstitution != null )
555520 realPointer = templateSubstitution . Replacement . Type . Desugar ( ) as PointerType ;
556521 realPointer = realPointer ?? pointer ;
557- var pointee = pointer . Pointee . Desugar ( ) ;
558522 if ( Context . Function != null &&
559523 ( realPointer . IsPrimitiveTypeConvertibleToRef ( ) ||
560524 ( templateSubstitution != null && realPointer . Pointee . IsEnumType ( ) ) ) &&
@@ -597,23 +561,20 @@ public override bool VisitPointerType(PointerType pointer, TypeQualifiers quals)
597561 var param = Context . Parameter ;
598562 var isRefParam = param != null && ( param . IsInOut || param . IsOut ) ;
599563
564+ var pointee = pointer . Pointee . Desugar ( ) ;
600565 if ( pointee . IsConstCharString ( ) && isRefParam )
601566 {
602567 if ( param . IsOut )
603568 {
604569 Context . Return . Write ( "IntPtr.Zero" ) ;
605570 Context . ArgumentPrefix . Write ( "&" ) ;
571+ return true ;
606572 }
607- else if ( param . IsInOut )
608- {
609- Context . Return . Write ( MarshalStringToUnmanaged ( Context . Parameter . Name ) ) ;
573+ pointer . QualifiedPointee . Visit ( this ) ;
574+ if ( param . IsInOut )
610575 Context . ArgumentPrefix . Write ( "&" ) ;
611- }
612576 else
613- {
614- Context . Return . Write ( MarshalStringToUnmanaged ( Context . Parameter . Name ) ) ;
615577 Context . Cleanup . WriteLine ( "Marshal.FreeHGlobal({0});" , Context . ArgName ) ;
616- }
617578 return true ;
618579 }
619580
@@ -643,11 +604,9 @@ public override bool VisitPointerType(PointerType pointer, TypeQualifiers quals)
643604 return true ;
644605 }
645606
646- var marshalAsString = pointer . IsConstCharString ( ) ;
647607 var finalPointee = pointer . GetFinalPointee ( ) ;
648608 PrimitiveType primitive ;
649- if ( finalPointee . IsPrimitiveType ( out primitive ) || finalPointee . IsEnumType ( ) ||
650- marshalAsString )
609+ if ( finalPointee . IsPrimitiveType ( out primitive ) || finalPointee . IsEnumType ( ) )
651610 {
652611 // From MSDN: "note that a ref or out parameter is classified as a moveable
653612 // variable". This means we must create a local variable to hold the result
@@ -670,23 +629,13 @@ public override bool VisitPointerType(PointerType pointer, TypeQualifiers quals)
670629 }
671630 else
672631 {
673- if ( ! marshalAsString &&
674- Context . Context . Options . MarshalCharAsManagedChar &&
632+ if ( Context . Context . Options . MarshalCharAsManagedChar &&
675633 primitive == PrimitiveType . Char )
676634 Context . Return . Write ( $ "({ typePrinter . PrintNative ( pointer ) } ) ") ;
677635
678- if ( marshalAsString && ( Context . MarshalKind == MarshalKind . NativeField ||
679- Context . MarshalKind == MarshalKind . VTableReturnValue ||
680- Context . MarshalKind == MarshalKind . Variable ) )
681- {
682- Context . Return . Write ( MarshalStringToUnmanaged ( Context . Parameter . Name ) ) ;
683- }
684- else
685- {
686- if ( qualifiedPointer . IsConstRefToPrimitive ( ) )
687- Context . Return . Write ( "&" ) ;
688- Context . Return . Write ( Context . Parameter . Name ) ;
689- }
636+ if ( qualifiedPointer . IsConstRefToPrimitive ( ) )
637+ Context . Return . Write ( "&" ) ;
638+ Context . Return . Write ( Context . Parameter . Name ) ;
690639 }
691640
692641 return true ;
@@ -695,21 +644,6 @@ public override bool VisitPointerType(PointerType pointer, TypeQualifiers quals)
695644 return pointer . QualifiedPointee . Visit ( this ) ;
696645 }
697646
698- private string MarshalStringToUnmanaged ( string varName )
699- {
700- if ( Equals ( Context . Context . Options . Encoding , Encoding . ASCII ) )
701- {
702- return string . Format ( "Marshal.StringToHGlobalAnsi({0})" , varName ) ;
703- }
704- if ( Equals ( Context . Context . Options . Encoding , Encoding . Unicode ) ||
705- Equals ( Context . Context . Options . Encoding , Encoding . BigEndianUnicode ) )
706- {
707- return string . Format ( "Marshal.StringToHGlobalUni({0})" , varName ) ;
708- }
709- throw new NotSupportedException ( string . Format ( "{0} is not supported yet." ,
710- Context . Context . Options . Encoding . EncodingName ) ) ;
711- }
712-
713647 public override bool VisitPrimitiveType ( PrimitiveType primitive , TypeQualifiers quals )
714648 {
715649 switch ( primitive )
0 commit comments