public override bool VisitPointerType(PointerType pointer, TypeQualifiers quals) { if (!VisitType(pointer, quals)) { return(false); } var param = Context.Parameter; var isRefParam = param != null && (param.IsInOut || param.IsOut); var pointee = pointer.Pointee.Desugar(); if (pointee.IsConstCharString()) { if (param.IsOut) { MarshalString(pointee); Context.Return.Write("IntPtr.Zero"); Context.ArgumentPrefix.Write("&"); return(true); } if (param.IsInOut) { MarshalString(pointee); pointer.QualifiedPointee.Visit(this); Context.ArgumentPrefix.Write("&"); return(true); } if (pointer.IsReference) { Context.Return.Write($@"({typePrinter.PrintNative( pointee.GetQualifiedPointee())}*) "); pointer.QualifiedPointee.Visit(this); Context.ArgumentPrefix.Write("&"); return(true); } } var finalPointee = (pointee.GetFinalPointee() ?? pointee).Desugar(); if (finalPointee.IsPrimitiveType(out PrimitiveType primitive) || finalPointee.IsEnumType()) { if (isRefParam) { var local = Generator.GeneratedIdentifier($@"{ param.Name}{Context.ParameterIndex}"); Context.Before.WriteLine($@"fixed ({ pointer.Visit(typePrinter)} {local} = &{param.Name})"); Context.HasCodeBlock = true; Context.Before.WriteOpenBraceAndIndent(); Context.Return.Write(local); return(true); } if (Context.Context.Options.MarshalCharAsManagedChar && primitive == PrimitiveType.Char) { Context.Return.Write($"({typePrinter.PrintNative(pointer)}) "); Context.Return.Write(param.Name); return(true); } pointer.QualifiedPointee.Visit(this); if (Context.Parameter.IsIndirect) { Context.ArgumentPrefix.Write("&"); } bool isVoid = primitive == PrimitiveType.Void && pointee.IsAddress() && pointer.IsReference(); if (pointer.Pointee.Desugar(false) is TemplateParameterSubstitutionType || isVoid) { var local = Generator.GeneratedIdentifier($@"{ param.Name}{Context.ParameterIndex}"); string cast = isVoid ? $@"({pointee.Visit( new CppTypePrinter { PrintTypeQualifiers = false })}) " : string.Empty; Context.Before.WriteLine($"var {local} = {cast}{Context.Return};"); Context.Return.StringBuilder.Clear(); Context.Return.Write(local); } if (new QualifiedType(pointer, quals).IsConstRefToPrimitive()) { Context.Return.StringBuilder.Insert(0, '&'); } return(true); } if (pointee.TryGetClass(out Class @class) && @class.IsValueType) { if (Context.Parameter.Usage == ParameterUsage.Out) { var qualifiedIdentifier = (@class.OriginalClass ?? @class).Visit(typePrinter); Context.Before.WriteLine("var {0} = new {1}.{2}();", Generator.GeneratedIdentifier(Context.ArgName), qualifiedIdentifier, Helpers.InternalStruct); } else { Context.Before.WriteLine("var {0} = {1}.{2};", Generator.GeneratedIdentifier(Context.ArgName), Context.Parameter.Name, Helpers.InstanceIdentifier); } Context.Return.Write("new global::System.IntPtr(&{0})", Generator.GeneratedIdentifier(Context.ArgName)); return(true); } return(pointer.QualifiedPointee.Visit(this)); }