From 5a27285f65477b2524c5d03488c539a98a0fe52b Mon Sep 17 00:00:00 2001 From: triton Date: Sun, 29 Jun 2014 20:54:05 +0100 Subject: [PATCH] Fixed CLI marshaling of in/out parameters under some cases. Closes pull #269. --- src/Generator/Generators/CLI/CLIMarshal.cs | 7 ++- .../Generators/CLI/CLISourcesTemplate.cs | 59 +++++++++++-------- 2 files changed, 39 insertions(+), 27 deletions(-) diff --git a/src/Generator/Generators/CLI/CLIMarshal.cs b/src/Generator/Generators/CLI/CLIMarshal.cs index 45799bac..70fcb224 100644 --- a/src/Generator/Generators/CLI/CLIMarshal.cs +++ b/src/Generator/Generators/CLI/CLIMarshal.cs @@ -451,9 +451,12 @@ namespace CppSharp.Generators.CLI Enumeration @enum; if (pointee.TryGetEnum(out @enum)) { + var isRef = Context.Parameter.Usage == ParameterUsage.Out || + Context.Parameter.Usage == ParameterUsage.InOut; + ArgumentPrefix.Write("&"); - Context.Return.Write("(::{0})*{1}", @enum.QualifiedOriginalName, - Context.Parameter.Name); + Context.Return.Write("(::{0}){1}{2}", @enum.QualifiedOriginalName, + isRef ? string.Empty : "*", Context.Parameter.Name); return true; } diff --git a/src/Generator/Generators/CLI/CLISourcesTemplate.cs b/src/Generator/Generators/CLI/CLISourcesTemplate.cs index 68bd47b9..7484a178 100644 --- a/src/Generator/Generators/CLI/CLISourcesTemplate.cs +++ b/src/Generator/Generators/CLI/CLISourcesTemplate.cs @@ -1063,47 +1063,56 @@ namespace CppSharp.Generators.CLI var argName = "arg" + paramIndex.ToString(CultureInfo.InvariantCulture); - if (param.IsOut || param.IsInOut) + var isRef = param.IsOut || param.IsInOut; + // Since both pointers and references to types are wrapped as CLI + // tracking references when using in/out, we normalize them here to be able + // to use the same code for marshaling. + var paramType = param.Type; + if (paramType is PointerType && isRef) { - var paramType = param.Type; - if (paramType is PointerType) - { - if (!paramType.IsReference()) - paramMarshal.Prefix = "&"; - paramType = (paramType as PointerType).Pointee; - } + if (!paramType.IsReference()) + paramMarshal.Prefix = "&"; + paramType = (paramType as PointerType).Pointee; + } + + var effectiveParam = new Parameter(param) + { + QualifiedType = new QualifiedType(paramType) + }; + + var ctx = new MarshalContext(Driver) + { + Parameter = effectiveParam, + ParameterIndex = paramIndex, + ArgName = argName, + Function = function + }; + + var marshal = new CLIMarshalManagedToNativePrinter(ctx); + effectiveParam.Visit(marshal); + if (string.IsNullOrEmpty(marshal.Context.Return)) + throw new Exception(string.Format("Cannot marshal argument of function '{0}'", + function.QualifiedOriginalName)); + + if (isRef) + { var typePrinter = new CppTypePrinter(Driver.TypeDatabase); var type = paramType.Visit(typePrinter); if (param.IsInOut) - WriteLine("{0} {1} = {2};", type, argName, param.Name); + WriteLine("{0} {1} = {2};", type, argName, marshal.Context.Return); else WriteLine("{0} {1};", type, argName); } else { - var ctx = new MarshalContext(Driver) - { - Parameter = param, - ParameterIndex = paramIndex, - ArgName = argName, - Function = function - }; - - var marshal = new CLIMarshalManagedToNativePrinter(ctx); - param.Visit(marshal); - - if (string.IsNullOrEmpty(marshal.Context.Return)) - throw new Exception(string.Format("Cannot marshal argument of function '{0}'", - function.QualifiedOriginalName)); - if (!string.IsNullOrWhiteSpace(marshal.Context.SupportBefore)) Write(marshal.Context.SupportBefore); WriteLine("auto {0}{1} = {2};", marshal.VarPrefix, argName, marshal.Context.Return); - argName = marshal.ArgumentPrefix + argName; + paramMarshal.Prefix = marshal.ArgumentPrefix; } paramMarshal.Name = argName;