diff --git a/src/Generator/Generators/CLI/CLISourcesTemplate.cs b/src/Generator/Generators/CLI/CLISourcesTemplate.cs index 35e3a2fa..7a090b7a 100644 --- a/src/Generator/Generators/CLI/CLISourcesTemplate.cs +++ b/src/Generator/Generators/CLI/CLISourcesTemplate.cs @@ -644,7 +644,7 @@ namespace Cxxi.Generators.CLI var @params = GenerateFunctionParamsMarshal(function.Parameters, function); if (needsReturn) - Write("auto ret = "); + Write("auto {0}ret = ",(function.ReturnType.IsReference())? "&": string.Empty); if (isValueType) { @@ -668,6 +668,30 @@ namespace Cxxi.Generators.CLI GenerateFunctionParams(@params); WriteLine(");"); + foreach(var paramInfo in @params) + { + var param = paramInfo.Param; + if(param.Usage != ParameterUsage.Out && param.Usage != ParameterUsage.Ref) + continue; + + var nativeVarName = paramInfo.Name; + + var ctx = new MarshalContext(Driver) + { + ArgName = nativeVarName, + ReturnVarName = nativeVarName, + ReturnType = param.Type + }; + + var marshal = new CLIMarshalNativeToManagedPrinter(ctx); + param.Visit(marshal); + + if (!string.IsNullOrWhiteSpace(marshal.Context.SupportBefore)) + Write(marshal.Context.SupportBefore); + + WriteLine("{0} = {1};",param.Name,marshal.Context.Return); + } + if (needsReturn) { var ctx = new MarshalContext(Driver) @@ -728,28 +752,42 @@ namespace Cxxi.Generators.CLI var argName = "arg" + paramIndex.ToString(CultureInfo.InvariantCulture); - var ctx = new MarshalContext(Driver) - { - Parameter = param, - ParameterIndex = paramIndex, - ArgName = argName, - Function = function - }; + if (param.Usage == ParameterUsage.Out) + { + var paramType = param.Type; + if (paramType.IsReference()) + paramType = (paramType as PointerType).Pointee; - var marshal = new CLIMarshalManagedToNativePrinter(ctx); + var typePrinter = new CppTypePrinter(Driver.TypeDatabase); + var type = paramType.Visit(typePrinter); - param.Visit(marshal); + WriteLine("{0} {1};", type, argName); + } + else + { + var ctx = new MarshalContext(Driver) + { + Parameter = param, + ParameterIndex = paramIndex, + ArgName = argName, + Function = function + }; - if (string.IsNullOrEmpty(marshal.Context.Return)) - throw new Exception("Cannot marshal argument of function"); + var marshal = new CLIMarshalManagedToNativePrinter(ctx); - if (!string.IsNullOrWhiteSpace(marshal.Context.SupportBefore)) - Write(marshal.Context.SupportBefore); + param.Visit(marshal); + + if (string.IsNullOrEmpty(marshal.Context.Return)) + throw new Exception("Cannot marshal argument of function"); - WriteLine("auto {0}{1} = {2};", marshal.VarPrefix, argName, marshal.Context.Return); + 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; + } - var argText = marshal.ArgumentPrefix + argName; - return new ParamMarshal {Name = argText, Param = param}; + return new ParamMarshal {Name = argName, Param = param}; } public void GenerateFunctionParams(List @params) diff --git a/src/Generator/Generators/CLI/CLITypePrinter.cs b/src/Generator/Generators/CLI/CLITypePrinter.cs index 713df030..05b6852e 100644 --- a/src/Generator/Generators/CLI/CLITypePrinter.cs +++ b/src/Generator/Generators/CLI/CLITypePrinter.cs @@ -120,11 +120,21 @@ namespace Cxxi.Generators.CLI { var type = param.Type.Visit(this, param.QualifiedType.Qualifiers); var name = param.Name; + var str = ""; + if(param.Usage == ParameterUsage.Out) + str += "[System::Runtime::InteropServices::Out] "; + + str += type; + + if(param.Usage == ParameterUsage.Out || + param.Usage == ParameterUsage.Ref) + str += "%"; + if (hasName && !string.IsNullOrEmpty(name)) - return string.Format("{0} {1}", type, name); + str += " " + name; - return type; + return str; } public string VisitDelegate(FunctionType function) diff --git a/src/Generator/Library.cs b/src/Generator/Library.cs index ccc711c4..aa0f2cc3 100644 --- a/src/Generator/Library.cs +++ b/src/Generator/Library.cs @@ -217,6 +217,28 @@ namespace Cxxi } } + /// + /// + /// + /// first parameter has index 1 + public static void SetMethodParameterUsage(this Library library, + string className, string methodName, int parameterIndex, ParameterUsage usage) + { + if (parameterIndex <= 0 ) + throw new ArgumentException("parameterIndex"); + + foreach (var @class in library.FindClass(className)) + { + var method = @class.Methods.Find(m => m.Name == methodName); + if (method == null) + throw new ArgumentException("methodName"); + if (method.Parameters.Count < parameterIndex) + throw new ArgumentException("parameterIndex"); + + method.Parameters[parameterIndex - 1].Usage = usage; + } + } + public static void CopyClassFields(this Library library, string source, string destination) {