From b2364659414a2d66a8fad1173816814b556791d8 Mon Sep 17 00:00:00 2001 From: Date: Tue, 19 Jul 2011 01:20:54 -0400 Subject: [PATCH] Add ByRef attribute for value types returned by ref and failing test --- src/Mono.Cxxi/Attributes.cs | 9 + src/generator/Templates/CSharp/CSharpClass.cs | 264 +++++++++--------- src/generator/Templates/CSharp/CSharpClass.tt | 28 +- .../Templates/CSharp/CSharpLanguage.cs | 21 +- tests/MarshalingTests.cs | 7 + tests/Native/MarshalingTests.h | 4 + 6 files changed, 188 insertions(+), 145 deletions(-) diff --git a/src/Mono.Cxxi/Attributes.cs b/src/Mono.Cxxi/Attributes.cs index 10cd5283..6d00fdba 100644 --- a/src/Mono.Cxxi/Attributes.cs +++ b/src/Mono.Cxxi/Attributes.cs @@ -49,9 +49,14 @@ namespace Mono.Cxxi { [AttributeUsage (AttributeTargets.Method)] public class CopyConstructorAttribute : Attribute {} + // applied when the target would normally be passed by reference (e.g. class) [AttributeUsage (AttributeTargets.Parameter | AttributeTargets.ReturnValue)] public class ByValAttribute : Attribute {} + // used for byref return of things that would normally be passed by value (e.g. int&) + [AttributeUsage (AttributeTargets.ReturnValue)] + public class ByRefAttribute : Attribute {} + [AttributeUsage (AttributeTargets.Parameter | AttributeTargets.ReturnValue)] public class MangleAsAttribute : Attribute { public CppType MangleType { get; private set; } @@ -140,6 +145,10 @@ using Mono.Cxxi; { return icap.IsDefined (typeof (ByValAttribute), false); } + public virtual bool IsByRef (ICustomAttributeProvider icap, Type type) + { + return type.IsByRef || icap.IsDefined (typeof (ByRefAttribute), false); + } public virtual CppType GetMangleType (ICustomAttributeProvider icap, Type managedType) { diff --git a/src/generator/Templates/CSharp/CSharpClass.cs b/src/generator/Templates/CSharp/CSharpClass.cs index d38cf060..31c46479 100644 --- a/src/generator/Templates/CSharp/CSharpClass.cs +++ b/src/generator/Templates/CSharp/CSharpClass.cs @@ -19,11 +19,11 @@ namespace Templates { public partial class CSharpClass : Base { - #line 280 "/Users/alex/OpenSource/cppinterop/src/generator/Templates/CSharp/CSharpClass.tt" + #line 283 "/Users/alex/OpenSource/cppinterop/src/generator/Templates/CSharp/CSharpClass.tt" private void WriteMethodHeader (Method method, string layoutClass, bool isNonPrimaryOverride, bool @protected) { - var returnType = CSharpLanguage.TypeName (method.ReturnType); + var returnType = CSharpLanguage.TypeName (method.ReturnType, CSharpLanguage.Context.Return); if (!isNonPrimaryOverride && method.IsVirtual) WriteLine ("[OverrideNative (\"{0}\")]", method.Name); @@ -63,7 +63,7 @@ private void WriteParameters (IList parameters, bool writeType, bool if (i != 0) Write (", "); - var type = CSharpLanguage.TypeName (parameters [i].Type); + var type = CSharpLanguage.TypeName (parameters [i].Type, CSharpLanguage.Context.Parameter); if (writeAttributes) { var mangleAs = parameters [i].Type.ToString (); @@ -73,11 +73,6 @@ private void WriteParameters (IList parameters, bool writeType, bool Write ("[ByVal] "); } - if (type.EndsWith ("&")) { - Write ("ref "); - type = CSharpLanguage.TypeName (type.TrimEnd ('&')); - } - if (writeType) { Write (type); Write (" "); @@ -107,6 +102,12 @@ private bool IsByVal (CppType t) !t.Modifiers.Contains (CppModifiers.Reference) && !t.Modifiers.Contains (CppModifiers.Array)); } +private bool IsByRef (CppType t) +{ + return ((t.ElementType != CppTypes.Class && t.ElementType != CppTypes.Struct) && + t.Modifiers.Contains (CppModifiers.Pointer) || + t.Modifiers.Contains (CppModifiers.Reference)); +} #line default #line hidden @@ -330,10 +331,13 @@ private bool IsByVal (CppType t) if (IsByVal (method.ReturnType)) { Write ("[return: ByVal] "); } + if (IsByRef (method.ReturnType)) { + Write ("[return: ByRef] "); + } if (method.IsConstructor) Write ("CppInstancePtr"); else - Write (CSharpLanguage.TypeName (method.ReturnType)); + Write (CSharpLanguage.TypeName (method.ReturnType, CSharpLanguage.Context.Return)); Write (" "); Write (CSharpLanguage.SafeIdentifier (method.Name)); @@ -348,251 +352,251 @@ private bool IsByVal (CppType t) Write (");\n"); } foreach (var field in Class.Fields.Where (f => f.Access != Access.@private)) { - WriteLine ("CppField<{0}> {1} {{ get; }}", CSharpLanguage.TypeName (field.Type), CSharpLanguage.SafeIdentifier (field.Name)); + WriteLine ("CppField<{0}> {1} {{ get; }}", CSharpLanguage.TypeName (field.Type, CSharpLanguage.Context.Generic), CSharpLanguage.SafeIdentifier (field.Name)); } ClearIndent (); #line default #line hidden - #line 72 "/Users/alex/OpenSource/cppinterop/src/generator/Templates/CSharp/CSharpClass.tt" + #line 75 "/Users/alex/OpenSource/cppinterop/src/generator/Templates/CSharp/CSharpClass.tt" this.Write("\t\t}\n"); #line default #line hidden - #line 73 "/Users/alex/OpenSource/cppinterop/src/generator/Templates/CSharp/CSharpClass.tt" + #line 76 "/Users/alex/OpenSource/cppinterop/src/generator/Templates/CSharp/CSharpClass.tt" /* Native layout */ #line default #line hidden - #line 74 "/Users/alex/OpenSource/cppinterop/src/generator/Templates/CSharp/CSharpClass.tt" + #line 77 "/Users/alex/OpenSource/cppinterop/src/generator/Templates/CSharp/CSharpClass.tt" this.Write("\t\tprivate struct "); #line default #line hidden - #line 74 "/Users/alex/OpenSource/cppinterop/src/generator/Templates/CSharp/CSharpClass.tt" + #line 77 "/Users/alex/OpenSource/cppinterop/src/generator/Templates/CSharp/CSharpClass.tt" this.Write(this.ToStringHelper.ToStringWithCulture( layout )); #line default #line hidden - #line 74 "/Users/alex/OpenSource/cppinterop/src/generator/Templates/CSharp/CSharpClass.tt" + #line 77 "/Users/alex/OpenSource/cppinterop/src/generator/Templates/CSharp/CSharpClass.tt" this.Write(" {\n"); #line default #line hidden - #line 75 "/Users/alex/OpenSource/cppinterop/src/generator/Templates/CSharp/CSharpClass.tt" + #line 78 "/Users/alex/OpenSource/cppinterop/src/generator/Templates/CSharp/CSharpClass.tt" foreach (var field in Class.Fields) { #line default #line hidden - #line 76 "/Users/alex/OpenSource/cppinterop/src/generator/Templates/CSharp/CSharpClass.tt" + #line 79 "/Users/alex/OpenSource/cppinterop/src/generator/Templates/CSharp/CSharpClass.tt" this.Write("\t\t\tpublic "); #line default #line hidden - #line 76 "/Users/alex/OpenSource/cppinterop/src/generator/Templates/CSharp/CSharpClass.tt" - this.Write(this.ToStringHelper.ToStringWithCulture( CSharpLanguage.TypeName (field.Type) )); + #line 79 "/Users/alex/OpenSource/cppinterop/src/generator/Templates/CSharp/CSharpClass.tt" + this.Write(this.ToStringHelper.ToStringWithCulture( CSharpLanguage.TypeName (field.Type, CSharpLanguage.Context.Generic) )); #line default #line hidden - #line 76 "/Users/alex/OpenSource/cppinterop/src/generator/Templates/CSharp/CSharpClass.tt" + #line 79 "/Users/alex/OpenSource/cppinterop/src/generator/Templates/CSharp/CSharpClass.tt" this.Write(" "); #line default #line hidden - #line 76 "/Users/alex/OpenSource/cppinterop/src/generator/Templates/CSharp/CSharpClass.tt" + #line 79 "/Users/alex/OpenSource/cppinterop/src/generator/Templates/CSharp/CSharpClass.tt" this.Write(this.ToStringHelper.ToStringWithCulture( CSharpLanguage.SafeIdentifier (field.Name) )); #line default #line hidden - #line 76 "/Users/alex/OpenSource/cppinterop/src/generator/Templates/CSharp/CSharpClass.tt" + #line 79 "/Users/alex/OpenSource/cppinterop/src/generator/Templates/CSharp/CSharpClass.tt" this.Write(";\n"); #line default #line hidden - #line 77 "/Users/alex/OpenSource/cppinterop/src/generator/Templates/CSharp/CSharpClass.tt" + #line 80 "/Users/alex/OpenSource/cppinterop/src/generator/Templates/CSharp/CSharpClass.tt" } #line default #line hidden - #line 78 "/Users/alex/OpenSource/cppinterop/src/generator/Templates/CSharp/CSharpClass.tt" + #line 81 "/Users/alex/OpenSource/cppinterop/src/generator/Templates/CSharp/CSharpClass.tt" this.Write("\t\t}\n\n"); #line default #line hidden - #line 80 "/Users/alex/OpenSource/cppinterop/src/generator/Templates/CSharp/CSharpClass.tt" + #line 83 "/Users/alex/OpenSource/cppinterop/src/generator/Templates/CSharp/CSharpClass.tt" /* Native fields */ #line default #line hidden - #line 81 "/Users/alex/OpenSource/cppinterop/src/generator/Templates/CSharp/CSharpClass.tt" + #line 84 "/Users/alex/OpenSource/cppinterop/src/generator/Templates/CSharp/CSharpClass.tt" PushIndent ("\t\t"); foreach (var field in Class.Fields.Where (f => f.Access != Access.@private)) { var fieldName = CSharpLanguage.SafeIdentifier (field.Name); - WriteLine ("{0} {1} {2} {{", field.Access, CSharpLanguage.TypeName (field.Type), fieldName); + WriteLine ("{0} {1} {2} {{", field.Access, CSharpLanguage.TypeName (field.Type, CSharpLanguage.Context.Return), fieldName); #line default #line hidden - #line 85 "/Users/alex/OpenSource/cppinterop/src/generator/Templates/CSharp/CSharpClass.tt" + #line 88 "/Users/alex/OpenSource/cppinterop/src/generator/Templates/CSharp/CSharpClass.tt" this.Write("\t\t\tget {\n\t\t\t\treturn impl."); #line default #line hidden - #line 86 "/Users/alex/OpenSource/cppinterop/src/generator/Templates/CSharp/CSharpClass.tt" + #line 89 "/Users/alex/OpenSource/cppinterop/src/generator/Templates/CSharp/CSharpClass.tt" this.Write(this.ToStringHelper.ToStringWithCulture( fieldName )); #line default #line hidden - #line 86 "/Users/alex/OpenSource/cppinterop/src/generator/Templates/CSharp/CSharpClass.tt" + #line 89 "/Users/alex/OpenSource/cppinterop/src/generator/Templates/CSharp/CSharpClass.tt" this.Write(" [Native];\n\t\t\t}\n\t\t\tset {\n\t\t\t\timpl."); #line default #line hidden - #line 89 "/Users/alex/OpenSource/cppinterop/src/generator/Templates/CSharp/CSharpClass.tt" + #line 92 "/Users/alex/OpenSource/cppinterop/src/generator/Templates/CSharp/CSharpClass.tt" this.Write(this.ToStringHelper.ToStringWithCulture( fieldName )); #line default #line hidden - #line 89 "/Users/alex/OpenSource/cppinterop/src/generator/Templates/CSharp/CSharpClass.tt" + #line 92 "/Users/alex/OpenSource/cppinterop/src/generator/Templates/CSharp/CSharpClass.tt" this.Write(" [Native] = value;\n\t\t\t}\n\t\t}\n"); #line default #line hidden - #line 92 "/Users/alex/OpenSource/cppinterop/src/generator/Templates/CSharp/CSharpClass.tt" + #line 95 "/Users/alex/OpenSource/cppinterop/src/generator/Templates/CSharp/CSharpClass.tt" } ClearIndent(); #line default #line hidden - #line 93 "/Users/alex/OpenSource/cppinterop/src/generator/Templates/CSharp/CSharpClass.tt" + #line 96 "/Users/alex/OpenSource/cppinterop/src/generator/Templates/CSharp/CSharpClass.tt" this.Write("\n"); #line default #line hidden - #line 94 "/Users/alex/OpenSource/cppinterop/src/generator/Templates/CSharp/CSharpClass.tt" + #line 97 "/Users/alex/OpenSource/cppinterop/src/generator/Templates/CSharp/CSharpClass.tt" /* Subclass constructor */ #line default #line hidden - #line 95 "/Users/alex/OpenSource/cppinterop/src/generator/Templates/CSharp/CSharpClass.tt" + #line 98 "/Users/alex/OpenSource/cppinterop/src/generator/Templates/CSharp/CSharpClass.tt" this.Write("\t\tpublic "); #line default #line hidden - #line 95 "/Users/alex/OpenSource/cppinterop/src/generator/Templates/CSharp/CSharpClass.tt" + #line 98 "/Users/alex/OpenSource/cppinterop/src/generator/Templates/CSharp/CSharpClass.tt" this.Write(this.ToStringHelper.ToStringWithCulture( wrapper )); #line default #line hidden - #line 95 "/Users/alex/OpenSource/cppinterop/src/generator/Templates/CSharp/CSharpClass.tt" + #line 98 "/Users/alex/OpenSource/cppinterop/src/generator/Templates/CSharp/CSharpClass.tt" this.Write(" (CppTypeInfo subClass)\n\t\t"); #line default #line hidden - #line 96 "/Users/alex/OpenSource/cppinterop/src/generator/Templates/CSharp/CSharpClass.tt" + #line 99 "/Users/alex/OpenSource/cppinterop/src/generator/Templates/CSharp/CSharpClass.tt" this.Write(this.ToStringHelper.ToStringWithCulture( layoutClass )); #line default #line hidden - #line 96 "/Users/alex/OpenSource/cppinterop/src/generator/Templates/CSharp/CSharpClass.tt" + #line 99 "/Users/alex/OpenSource/cppinterop/src/generator/Templates/CSharp/CSharpClass.tt" this.Write("\n\t\t\tsubClass.AddBase (impl.TypeInfo);\n\t\t"); #line default #line hidden - #line 98 "/Users/alex/OpenSource/cppinterop/src/generator/Templates/CSharp/CSharpClass.tt" + #line 101 "/Users/alex/OpenSource/cppinterop/src/generator/Templates/CSharp/CSharpClass.tt" this.Write(this.ToStringHelper.ToStringWithCulture( initBases )); #line default #line hidden - #line 98 "/Users/alex/OpenSource/cppinterop/src/generator/Templates/CSharp/CSharpClass.tt" + #line 101 "/Users/alex/OpenSource/cppinterop/src/generator/Templates/CSharp/CSharpClass.tt" this.Write("\n\n"); #line default #line hidden - #line 100 "/Users/alex/OpenSource/cppinterop/src/generator/Templates/CSharp/CSharpClass.tt" + #line 103 "/Users/alex/OpenSource/cppinterop/src/generator/Templates/CSharp/CSharpClass.tt" /* Native constructor */ #line default #line hidden - #line 101 "/Users/alex/OpenSource/cppinterop/src/generator/Templates/CSharp/CSharpClass.tt" + #line 104 "/Users/alex/OpenSource/cppinterop/src/generator/Templates/CSharp/CSharpClass.tt" this.Write("\t\tpublic "); #line default #line hidden - #line 101 "/Users/alex/OpenSource/cppinterop/src/generator/Templates/CSharp/CSharpClass.tt" + #line 104 "/Users/alex/OpenSource/cppinterop/src/generator/Templates/CSharp/CSharpClass.tt" this.Write(this.ToStringHelper.ToStringWithCulture( wrapper )); #line default #line hidden - #line 101 "/Users/alex/OpenSource/cppinterop/src/generator/Templates/CSharp/CSharpClass.tt" + #line 104 "/Users/alex/OpenSource/cppinterop/src/generator/Templates/CSharp/CSharpClass.tt" this.Write(" (CppInstancePtr native)\n\t\t"); #line default #line hidden - #line 102 "/Users/alex/OpenSource/cppinterop/src/generator/Templates/CSharp/CSharpClass.tt" + #line 105 "/Users/alex/OpenSource/cppinterop/src/generator/Templates/CSharp/CSharpClass.tt" this.Write(this.ToStringHelper.ToStringWithCulture( layoutClass )); #line default #line hidden - #line 102 "/Users/alex/OpenSource/cppinterop/src/generator/Templates/CSharp/CSharpClass.tt" + #line 105 "/Users/alex/OpenSource/cppinterop/src/generator/Templates/CSharp/CSharpClass.tt" this.Write("\n\t\t\tNative = native;\n\t\t"); #line default #line hidden - #line 104 "/Users/alex/OpenSource/cppinterop/src/generator/Templates/CSharp/CSharpClass.tt" + #line 107 "/Users/alex/OpenSource/cppinterop/src/generator/Templates/CSharp/CSharpClass.tt" this.Write(this.ToStringHelper.ToStringWithCulture( initBases )); #line default #line hidden - #line 104 "/Users/alex/OpenSource/cppinterop/src/generator/Templates/CSharp/CSharpClass.tt" + #line 107 "/Users/alex/OpenSource/cppinterop/src/generator/Templates/CSharp/CSharpClass.tt" this.Write("\n\n"); #line default #line hidden - #line 106 "/Users/alex/OpenSource/cppinterop/src/generator/Templates/CSharp/CSharpClass.tt" + #line 109 "/Users/alex/OpenSource/cppinterop/src/generator/Templates/CSharp/CSharpClass.tt" /* Wrapper methods */ #line default #line hidden - #line 107 "/Users/alex/OpenSource/cppinterop/src/generator/Templates/CSharp/CSharpClass.tt" + #line 110 "/Users/alex/OpenSource/cppinterop/src/generator/Templates/CSharp/CSharpClass.tt" PushIndent ("\t\t"); foreach (var method in Class.Methods.Where (m => m.GenWrapperMethod)) { var methodName = CSharpLanguage.SafeIdentifier (method.Name); @@ -625,23 +629,23 @@ private bool IsByVal (CppType t) #line default #line hidden - #line 135 "/Users/alex/OpenSource/cppinterop/src/generator/Templates/CSharp/CSharpClass.tt" + #line 138 "/Users/alex/OpenSource/cppinterop/src/generator/Templates/CSharp/CSharpClass.tt" this.Write("\n"); #line default #line hidden - #line 136 "/Users/alex/OpenSource/cppinterop/src/generator/Templates/CSharp/CSharpClass.tt" + #line 139 "/Users/alex/OpenSource/cppinterop/src/generator/Templates/CSharp/CSharpClass.tt" /* Wrapper properties */ #line default #line hidden - #line 137 "/Users/alex/OpenSource/cppinterop/src/generator/Templates/CSharp/CSharpClass.tt" + #line 140 "/Users/alex/OpenSource/cppinterop/src/generator/Templates/CSharp/CSharpClass.tt" PushIndent ("\t\t"); foreach (var prop in Class.Properties) { var propName = CSharpLanguage.SafeIdentifier (prop.Name); - var type = CSharpLanguage.TypeName (prop.Type); + var type = CSharpLanguage.TypeName (prop.Type, CSharpLanguage.Context.Return); Write (CurrentIndent + "public "); @@ -686,218 +690,218 @@ private bool IsByVal (CppType t) #line default #line hidden - #line 181 "/Users/alex/OpenSource/cppinterop/src/generator/Templates/CSharp/CSharpClass.tt" + #line 184 "/Users/alex/OpenSource/cppinterop/src/generator/Templates/CSharp/CSharpClass.tt" this.Write("\n\t\tpublic "); #line default #line hidden - #line 182 "/Users/alex/OpenSource/cppinterop/src/generator/Templates/CSharp/CSharpClass.tt" + #line 185 "/Users/alex/OpenSource/cppinterop/src/generator/Templates/CSharp/CSharpClass.tt" this.Write(this.ToStringHelper.ToStringWithCulture( hasBase? "override" : "virtual" )); #line default #line hidden - #line 182 "/Users/alex/OpenSource/cppinterop/src/generator/Templates/CSharp/CSharpClass.tt" + #line 185 "/Users/alex/OpenSource/cppinterop/src/generator/Templates/CSharp/CSharpClass.tt" this.Write(" void Dispose ()\n\t\t{\n"); #line default #line hidden - #line 184 "/Users/alex/OpenSource/cppinterop/src/generator/Templates/CSharp/CSharpClass.tt" + #line 187 "/Users/alex/OpenSource/cppinterop/src/generator/Templates/CSharp/CSharpClass.tt" if (Class.Methods.Any (m => m.IsDestructor && !m.IsArtificial)) { #line default #line hidden - #line 185 "/Users/alex/OpenSource/cppinterop/src/generator/Templates/CSharp/CSharpClass.tt" + #line 188 "/Users/alex/OpenSource/cppinterop/src/generator/Templates/CSharp/CSharpClass.tt" this.Write("\t\t\timpl.Destruct (Native);\n"); #line default #line hidden - #line 186 "/Users/alex/OpenSource/cppinterop/src/generator/Templates/CSharp/CSharpClass.tt" + #line 189 "/Users/alex/OpenSource/cppinterop/src/generator/Templates/CSharp/CSharpClass.tt" } #line default #line hidden - #line 187 "/Users/alex/OpenSource/cppinterop/src/generator/Templates/CSharp/CSharpClass.tt" + #line 190 "/Users/alex/OpenSource/cppinterop/src/generator/Templates/CSharp/CSharpClass.tt" this.Write("\t\t\tNative.Dispose ();\n\t\t}\n\n\t\tprivate void __cxxi_LayoutClass ()\n\t\t{\n"); #line default #line hidden - #line 192 "/Users/alex/OpenSource/cppinterop/src/generator/Templates/CSharp/CSharpClass.tt" + #line 195 "/Users/alex/OpenSource/cppinterop/src/generator/Templates/CSharp/CSharpClass.tt" foreach (var npBase in Class.BaseClasses.Skip (1)) { #line default #line hidden - #line 193 "/Users/alex/OpenSource/cppinterop/src/generator/Templates/CSharp/CSharpClass.tt" + #line 196 "/Users/alex/OpenSource/cppinterop/src/generator/Templates/CSharp/CSharpClass.tt" this.Write("\t\t\tnew "); #line default #line hidden - #line 193 "/Users/alex/OpenSource/cppinterop/src/generator/Templates/CSharp/CSharpClass.tt" + #line 196 "/Users/alex/OpenSource/cppinterop/src/generator/Templates/CSharp/CSharpClass.tt" this.Write(this.ToStringHelper.ToStringWithCulture( npBase.Name )); #line default #line hidden - #line 193 "/Users/alex/OpenSource/cppinterop/src/generator/Templates/CSharp/CSharpClass.tt" + #line 196 "/Users/alex/OpenSource/cppinterop/src/generator/Templates/CSharp/CSharpClass.tt" this.Write(" (impl.TypeInfo);\n"); #line default #line hidden - #line 194 "/Users/alex/OpenSource/cppinterop/src/generator/Templates/CSharp/CSharpClass.tt" + #line 197 "/Users/alex/OpenSource/cppinterop/src/generator/Templates/CSharp/CSharpClass.tt" } #line default #line hidden - #line 195 "/Users/alex/OpenSource/cppinterop/src/generator/Templates/CSharp/CSharpClass.tt" + #line 198 "/Users/alex/OpenSource/cppinterop/src/generator/Templates/CSharp/CSharpClass.tt" this.Write("\t\t\timpl.TypeInfo.CompleteType ();\n\t\t}\n\n"); #line default #line hidden - #line 198 "/Users/alex/OpenSource/cppinterop/src/generator/Templates/CSharp/CSharpClass.tt" + #line 201 "/Users/alex/OpenSource/cppinterop/src/generator/Templates/CSharp/CSharpClass.tt" /* Make this wrapper castable to non-primary bases */ foreach (var npBase in Class.BaseClasses.Skip (1)) { #line default #line hidden - #line 200 "/Users/alex/OpenSource/cppinterop/src/generator/Templates/CSharp/CSharpClass.tt" + #line 203 "/Users/alex/OpenSource/cppinterop/src/generator/Templates/CSharp/CSharpClass.tt" this.Write("\n#region Non-primary base class implementation for "); #line default #line hidden - #line 201 "/Users/alex/OpenSource/cppinterop/src/generator/Templates/CSharp/CSharpClass.tt" + #line 204 "/Users/alex/OpenSource/cppinterop/src/generator/Templates/CSharp/CSharpClass.tt" this.Write(this.ToStringHelper.ToStringWithCulture( npBase.Name )); #line default #line hidden - #line 201 "/Users/alex/OpenSource/cppinterop/src/generator/Templates/CSharp/CSharpClass.tt" + #line 204 "/Users/alex/OpenSource/cppinterop/src/generator/Templates/CSharp/CSharpClass.tt" this.Write("\n\t\tprivate class "); #line default #line hidden - #line 202 "/Users/alex/OpenSource/cppinterop/src/generator/Templates/CSharp/CSharpClass.tt" + #line 205 "/Users/alex/OpenSource/cppinterop/src/generator/Templates/CSharp/CSharpClass.tt" this.Write(this.ToStringHelper.ToStringWithCulture( wrapper + "__" + npBase.Name )); #line default #line hidden - #line 202 "/Users/alex/OpenSource/cppinterop/src/generator/Templates/CSharp/CSharpClass.tt" + #line 205 "/Users/alex/OpenSource/cppinterop/src/generator/Templates/CSharp/CSharpClass.tt" this.Write(" : "); #line default #line hidden - #line 202 "/Users/alex/OpenSource/cppinterop/src/generator/Templates/CSharp/CSharpClass.tt" + #line 205 "/Users/alex/OpenSource/cppinterop/src/generator/Templates/CSharp/CSharpClass.tt" this.Write(this.ToStringHelper.ToStringWithCulture( npBase.Name )); #line default #line hidden - #line 202 "/Users/alex/OpenSource/cppinterop/src/generator/Templates/CSharp/CSharpClass.tt" + #line 205 "/Users/alex/OpenSource/cppinterop/src/generator/Templates/CSharp/CSharpClass.tt" this.Write(" {\n\t\t\tpublic "); #line default #line hidden - #line 203 "/Users/alex/OpenSource/cppinterop/src/generator/Templates/CSharp/CSharpClass.tt" + #line 206 "/Users/alex/OpenSource/cppinterop/src/generator/Templates/CSharp/CSharpClass.tt" this.Write(this.ToStringHelper.ToStringWithCulture( wrapper )); #line default #line hidden - #line 203 "/Users/alex/OpenSource/cppinterop/src/generator/Templates/CSharp/CSharpClass.tt" + #line 206 "/Users/alex/OpenSource/cppinterop/src/generator/Templates/CSharp/CSharpClass.tt" this.Write(" instance;\n\t\t\tpublic "); #line default #line hidden - #line 204 "/Users/alex/OpenSource/cppinterop/src/generator/Templates/CSharp/CSharpClass.tt" + #line 207 "/Users/alex/OpenSource/cppinterop/src/generator/Templates/CSharp/CSharpClass.tt" this.Write(this.ToStringHelper.ToStringWithCulture( wrapper + "__" + npBase.Name )); #line default #line hidden - #line 204 "/Users/alex/OpenSource/cppinterop/src/generator/Templates/CSharp/CSharpClass.tt" + #line 207 "/Users/alex/OpenSource/cppinterop/src/generator/Templates/CSharp/CSharpClass.tt" this.Write(" ("); #line default #line hidden - #line 204 "/Users/alex/OpenSource/cppinterop/src/generator/Templates/CSharp/CSharpClass.tt" + #line 207 "/Users/alex/OpenSource/cppinterop/src/generator/Templates/CSharp/CSharpClass.tt" this.Write(this.ToStringHelper.ToStringWithCulture( wrapper )); #line default #line hidden - #line 204 "/Users/alex/OpenSource/cppinterop/src/generator/Templates/CSharp/CSharpClass.tt" + #line 207 "/Users/alex/OpenSource/cppinterop/src/generator/Templates/CSharp/CSharpClass.tt" this.Write(" instance)\n\t\t\t\t: base ("); #line default #line hidden - #line 205 "/Users/alex/OpenSource/cppinterop/src/generator/Templates/CSharp/CSharpClass.tt" + #line 208 "/Users/alex/OpenSource/cppinterop/src/generator/Templates/CSharp/CSharpClass.tt" this.Write(this.ToStringHelper.ToStringWithCulture( wrapper )); #line default #line hidden - #line 205 "/Users/alex/OpenSource/cppinterop/src/generator/Templates/CSharp/CSharpClass.tt" + #line 208 "/Users/alex/OpenSource/cppinterop/src/generator/Templates/CSharp/CSharpClass.tt" this.Write(".impl.TypeInfo.Cast (instance, typeof ("); #line default #line hidden - #line 205 "/Users/alex/OpenSource/cppinterop/src/generator/Templates/CSharp/CSharpClass.tt" + #line 208 "/Users/alex/OpenSource/cppinterop/src/generator/Templates/CSharp/CSharpClass.tt" this.Write(this.ToStringHelper.ToStringWithCulture( npBase.Name )); #line default #line hidden - #line 205 "/Users/alex/OpenSource/cppinterop/src/generator/Templates/CSharp/CSharpClass.tt" + #line 208 "/Users/alex/OpenSource/cppinterop/src/generator/Templates/CSharp/CSharpClass.tt" this.Write(")))\n\t\t\t{\n\t\t\t\t"); #line default #line hidden - #line 207 "/Users/alex/OpenSource/cppinterop/src/generator/Templates/CSharp/CSharpClass.tt" + #line 210 "/Users/alex/OpenSource/cppinterop/src/generator/Templates/CSharp/CSharpClass.tt" this.Write(this.ToStringHelper.ToStringWithCulture( wrapper )); #line default #line hidden - #line 207 "/Users/alex/OpenSource/cppinterop/src/generator/Templates/CSharp/CSharpClass.tt" + #line 210 "/Users/alex/OpenSource/cppinterop/src/generator/Templates/CSharp/CSharpClass.tt" this.Write(".impl.TypeInfo.InitNonPrimaryBase (this, instance, typeof ("); #line default #line hidden - #line 207 "/Users/alex/OpenSource/cppinterop/src/generator/Templates/CSharp/CSharpClass.tt" + #line 210 "/Users/alex/OpenSource/cppinterop/src/generator/Templates/CSharp/CSharpClass.tt" this.Write(this.ToStringHelper.ToStringWithCulture( npBase.Name )); #line default #line hidden - #line 207 "/Users/alex/OpenSource/cppinterop/src/generator/Templates/CSharp/CSharpClass.tt" + #line 210 "/Users/alex/OpenSource/cppinterop/src/generator/Templates/CSharp/CSharpClass.tt" this.Write("));\n\t\t\t\tthis.instance = instance;\n\t\t\t}\n\n"); #line default #line hidden - #line 211 "/Users/alex/OpenSource/cppinterop/src/generator/Templates/CSharp/CSharpClass.tt" + #line 214 "/Users/alex/OpenSource/cppinterop/src/generator/Templates/CSharp/CSharpClass.tt" PushIndent ("\t\t\t"); foreach (var method in npBase.Methods.Where (m => m.IsVirtual)) { @@ -927,163 +931,163 @@ foreach (var npBase in Class.BaseClasses.Skip (1)) { #line default #line hidden - #line 236 "/Users/alex/OpenSource/cppinterop/src/generator/Templates/CSharp/CSharpClass.tt" + #line 239 "/Users/alex/OpenSource/cppinterop/src/generator/Templates/CSharp/CSharpClass.tt" this.Write("\t\t}\n\t\tprivate "); #line default #line hidden - #line 237 "/Users/alex/OpenSource/cppinterop/src/generator/Templates/CSharp/CSharpClass.tt" + #line 240 "/Users/alex/OpenSource/cppinterop/src/generator/Templates/CSharp/CSharpClass.tt" this.Write(this.ToStringHelper.ToStringWithCulture( wrapper )); #line default #line hidden - #line 237 "/Users/alex/OpenSource/cppinterop/src/generator/Templates/CSharp/CSharpClass.tt" + #line 240 "/Users/alex/OpenSource/cppinterop/src/generator/Templates/CSharp/CSharpClass.tt" this.Write("__"); #line default #line hidden - #line 237 "/Users/alex/OpenSource/cppinterop/src/generator/Templates/CSharp/CSharpClass.tt" + #line 240 "/Users/alex/OpenSource/cppinterop/src/generator/Templates/CSharp/CSharpClass.tt" this.Write(this.ToStringHelper.ToStringWithCulture( npBase.Name )); #line default #line hidden - #line 237 "/Users/alex/OpenSource/cppinterop/src/generator/Templates/CSharp/CSharpClass.tt" + #line 240 "/Users/alex/OpenSource/cppinterop/src/generator/Templates/CSharp/CSharpClass.tt" this.Write(" __cxxi_"); #line default #line hidden - #line 237 "/Users/alex/OpenSource/cppinterop/src/generator/Templates/CSharp/CSharpClass.tt" + #line 240 "/Users/alex/OpenSource/cppinterop/src/generator/Templates/CSharp/CSharpClass.tt" this.Write(this.ToStringHelper.ToStringWithCulture( npBase.Name )); #line default #line hidden - #line 237 "/Users/alex/OpenSource/cppinterop/src/generator/Templates/CSharp/CSharpClass.tt" + #line 240 "/Users/alex/OpenSource/cppinterop/src/generator/Templates/CSharp/CSharpClass.tt" this.Write(";\n\t\tpublic "); #line default #line hidden - #line 238 "/Users/alex/OpenSource/cppinterop/src/generator/Templates/CSharp/CSharpClass.tt" + #line 241 "/Users/alex/OpenSource/cppinterop/src/generator/Templates/CSharp/CSharpClass.tt" this.Write(this.ToStringHelper.ToStringWithCulture( npBase.Name )); #line default #line hidden - #line 238 "/Users/alex/OpenSource/cppinterop/src/generator/Templates/CSharp/CSharpClass.tt" + #line 241 "/Users/alex/OpenSource/cppinterop/src/generator/Templates/CSharp/CSharpClass.tt" this.Write(" "); #line default #line hidden - #line 238 "/Users/alex/OpenSource/cppinterop/src/generator/Templates/CSharp/CSharpClass.tt" + #line 241 "/Users/alex/OpenSource/cppinterop/src/generator/Templates/CSharp/CSharpClass.tt" this.Write(this.ToStringHelper.ToStringWithCulture( npBase.Name )); #line default #line hidden - #line 238 "/Users/alex/OpenSource/cppinterop/src/generator/Templates/CSharp/CSharpClass.tt" + #line 241 "/Users/alex/OpenSource/cppinterop/src/generator/Templates/CSharp/CSharpClass.tt" this.Write(" { get { return __cxxi_"); #line default #line hidden - #line 238 "/Users/alex/OpenSource/cppinterop/src/generator/Templates/CSharp/CSharpClass.tt" + #line 241 "/Users/alex/OpenSource/cppinterop/src/generator/Templates/CSharp/CSharpClass.tt" this.Write(this.ToStringHelper.ToStringWithCulture( npBase.Name )); #line default #line hidden - #line 238 "/Users/alex/OpenSource/cppinterop/src/generator/Templates/CSharp/CSharpClass.tt" + #line 241 "/Users/alex/OpenSource/cppinterop/src/generator/Templates/CSharp/CSharpClass.tt" this.Write("; } }\n\t\tpublic static implicit operator "); #line default #line hidden - #line 239 "/Users/alex/OpenSource/cppinterop/src/generator/Templates/CSharp/CSharpClass.tt" + #line 242 "/Users/alex/OpenSource/cppinterop/src/generator/Templates/CSharp/CSharpClass.tt" this.Write(this.ToStringHelper.ToStringWithCulture( npBase.Name )); #line default #line hidden - #line 239 "/Users/alex/OpenSource/cppinterop/src/generator/Templates/CSharp/CSharpClass.tt" + #line 242 "/Users/alex/OpenSource/cppinterop/src/generator/Templates/CSharp/CSharpClass.tt" this.Write("("); #line default #line hidden - #line 239 "/Users/alex/OpenSource/cppinterop/src/generator/Templates/CSharp/CSharpClass.tt" + #line 242 "/Users/alex/OpenSource/cppinterop/src/generator/Templates/CSharp/CSharpClass.tt" this.Write(this.ToStringHelper.ToStringWithCulture( wrapper )); #line default #line hidden - #line 239 "/Users/alex/OpenSource/cppinterop/src/generator/Templates/CSharp/CSharpClass.tt" + #line 242 "/Users/alex/OpenSource/cppinterop/src/generator/Templates/CSharp/CSharpClass.tt" this.Write(" subClass)\n\t\t{\n\t\t\treturn subClass."); #line default #line hidden - #line 241 "/Users/alex/OpenSource/cppinterop/src/generator/Templates/CSharp/CSharpClass.tt" + #line 244 "/Users/alex/OpenSource/cppinterop/src/generator/Templates/CSharp/CSharpClass.tt" this.Write(this.ToStringHelper.ToStringWithCulture( npBase.Name )); #line default #line hidden - #line 241 "/Users/alex/OpenSource/cppinterop/src/generator/Templates/CSharp/CSharpClass.tt" + #line 244 "/Users/alex/OpenSource/cppinterop/src/generator/Templates/CSharp/CSharpClass.tt" this.Write(";\n\t\t}\n\t\tpublic static explicit operator "); #line default #line hidden - #line 243 "/Users/alex/OpenSource/cppinterop/src/generator/Templates/CSharp/CSharpClass.tt" + #line 246 "/Users/alex/OpenSource/cppinterop/src/generator/Templates/CSharp/CSharpClass.tt" this.Write(this.ToStringHelper.ToStringWithCulture( wrapper )); #line default #line hidden - #line 243 "/Users/alex/OpenSource/cppinterop/src/generator/Templates/CSharp/CSharpClass.tt" + #line 246 "/Users/alex/OpenSource/cppinterop/src/generator/Templates/CSharp/CSharpClass.tt" this.Write("("); #line default #line hidden - #line 243 "/Users/alex/OpenSource/cppinterop/src/generator/Templates/CSharp/CSharpClass.tt" + #line 246 "/Users/alex/OpenSource/cppinterop/src/generator/Templates/CSharp/CSharpClass.tt" this.Write(this.ToStringHelper.ToStringWithCulture( npBase.Name )); #line default #line hidden - #line 243 "/Users/alex/OpenSource/cppinterop/src/generator/Templates/CSharp/CSharpClass.tt" + #line 246 "/Users/alex/OpenSource/cppinterop/src/generator/Templates/CSharp/CSharpClass.tt" this.Write(" baseClass)\n\t\t{\n\t\t\tif (baseClass == null) return null;\n\t\t\tvar obj = baseClass as "); #line default #line hidden - #line 246 "/Users/alex/OpenSource/cppinterop/src/generator/Templates/CSharp/CSharpClass.tt" + #line 249 "/Users/alex/OpenSource/cppinterop/src/generator/Templates/CSharp/CSharpClass.tt" this.Write(this.ToStringHelper.ToStringWithCulture( wrapper + "__" + npBase.Name )); #line default #line hidden - #line 246 "/Users/alex/OpenSource/cppinterop/src/generator/Templates/CSharp/CSharpClass.tt" + #line 249 "/Users/alex/OpenSource/cppinterop/src/generator/Templates/CSharp/CSharpClass.tt" this.Write(";\n\t\t\tif (obj == null) throw new InvalidCastException ();\n\t\t\treturn obj.instance;\n\t\t}\n\n"); #line default #line hidden - #line 251 "/Users/alex/OpenSource/cppinterop/src/generator/Templates/CSharp/CSharpClass.tt" + #line 254 "/Users/alex/OpenSource/cppinterop/src/generator/Templates/CSharp/CSharpClass.tt" /* Add virtual methods of non-primary bases to this class proper so they can be overridden */ #line default #line hidden - #line 252 "/Users/alex/OpenSource/cppinterop/src/generator/Templates/CSharp/CSharpClass.tt" + #line 255 "/Users/alex/OpenSource/cppinterop/src/generator/Templates/CSharp/CSharpClass.tt" PushIndent ("\t\t"); foreach (var method in npBase.Methods.Where (m => m.IsVirtual)) { @@ -1106,67 +1110,67 @@ if (Class.BaseClasses.Count > 1) { #line default #line hidden - #line 270 "/Users/alex/OpenSource/cppinterop/src/generator/Templates/CSharp/CSharpClass.tt" + #line 273 "/Users/alex/OpenSource/cppinterop/src/generator/Templates/CSharp/CSharpClass.tt" this.Write("\t\tprivate void __cxxi_InitBases ()\n\t\t{\n"); #line default #line hidden - #line 272 "/Users/alex/OpenSource/cppinterop/src/generator/Templates/CSharp/CSharpClass.tt" + #line 275 "/Users/alex/OpenSource/cppinterop/src/generator/Templates/CSharp/CSharpClass.tt" foreach (var npBase in Class.BaseClasses.Skip (1)) { #line default #line hidden - #line 273 "/Users/alex/OpenSource/cppinterop/src/generator/Templates/CSharp/CSharpClass.tt" + #line 276 "/Users/alex/OpenSource/cppinterop/src/generator/Templates/CSharp/CSharpClass.tt" this.Write("\t\t\t__cxxi_"); #line default #line hidden - #line 273 "/Users/alex/OpenSource/cppinterop/src/generator/Templates/CSharp/CSharpClass.tt" + #line 276 "/Users/alex/OpenSource/cppinterop/src/generator/Templates/CSharp/CSharpClass.tt" this.Write(this.ToStringHelper.ToStringWithCulture( npBase.Name )); #line default #line hidden - #line 273 "/Users/alex/OpenSource/cppinterop/src/generator/Templates/CSharp/CSharpClass.tt" + #line 276 "/Users/alex/OpenSource/cppinterop/src/generator/Templates/CSharp/CSharpClass.tt" this.Write(" = new "); #line default #line hidden - #line 273 "/Users/alex/OpenSource/cppinterop/src/generator/Templates/CSharp/CSharpClass.tt" + #line 276 "/Users/alex/OpenSource/cppinterop/src/generator/Templates/CSharp/CSharpClass.tt" this.Write(this.ToStringHelper.ToStringWithCulture( wrapper + "__" + npBase.Name )); #line default #line hidden - #line 273 "/Users/alex/OpenSource/cppinterop/src/generator/Templates/CSharp/CSharpClass.tt" + #line 276 "/Users/alex/OpenSource/cppinterop/src/generator/Templates/CSharp/CSharpClass.tt" this.Write(" (this);\n"); #line default #line hidden - #line 274 "/Users/alex/OpenSource/cppinterop/src/generator/Templates/CSharp/CSharpClass.tt" + #line 277 "/Users/alex/OpenSource/cppinterop/src/generator/Templates/CSharp/CSharpClass.tt" } #line default #line hidden - #line 275 "/Users/alex/OpenSource/cppinterop/src/generator/Templates/CSharp/CSharpClass.tt" + #line 278 "/Users/alex/OpenSource/cppinterop/src/generator/Templates/CSharp/CSharpClass.tt" this.Write("\t\t}\n"); #line default #line hidden - #line 276 "/Users/alex/OpenSource/cppinterop/src/generator/Templates/CSharp/CSharpClass.tt" + #line 279 "/Users/alex/OpenSource/cppinterop/src/generator/Templates/CSharp/CSharpClass.tt" } #line default #line hidden - #line 277 "/Users/alex/OpenSource/cppinterop/src/generator/Templates/CSharp/CSharpClass.tt" + #line 280 "/Users/alex/OpenSource/cppinterop/src/generator/Templates/CSharp/CSharpClass.tt" this.Write("\t}\n}\n\n"); #line default diff --git a/src/generator/Templates/CSharp/CSharpClass.tt b/src/generator/Templates/CSharp/CSharpClass.tt index 33a0cf19..1546d5f6 100644 --- a/src/generator/Templates/CSharp/CSharpClass.tt +++ b/src/generator/Templates/CSharp/CSharpClass.tt @@ -48,10 +48,13 @@ namespace <#= Generator.Namespace #> { if (IsByVal (method.ReturnType)) { Write ("[return: ByVal] "); } + if (IsByRef (method.ReturnType)) { + Write ("[return: ByRef] "); + } if (method.IsConstructor) Write ("CppInstancePtr"); else - Write (CSharpLanguage.TypeName (method.ReturnType)); + Write (CSharpLanguage.TypeName (method.ReturnType, CSharpLanguage.Context.Return)); Write (" "); Write (CSharpLanguage.SafeIdentifier (method.Name)); @@ -66,14 +69,14 @@ namespace <#= Generator.Namespace #> { Write (");\n"); } foreach (var field in Class.Fields.Where (f => f.Access != Access.@private)) { - WriteLine ("CppField<{0}> {1} {{ get; }}", CSharpLanguage.TypeName (field.Type), CSharpLanguage.SafeIdentifier (field.Name)); + WriteLine ("CppField<{0}> {1} {{ get; }}", CSharpLanguage.TypeName (field.Type, CSharpLanguage.Context.Generic), CSharpLanguage.SafeIdentifier (field.Name)); } ClearIndent (); #> } <# /* Native layout */ #> private struct <#= layout #> { <# foreach (var field in Class.Fields) { #> - public <#= CSharpLanguage.TypeName (field.Type) #> <#= CSharpLanguage.SafeIdentifier (field.Name) #>; + public <#= CSharpLanguage.TypeName (field.Type, CSharpLanguage.Context.Generic) #> <#= CSharpLanguage.SafeIdentifier (field.Name) #>; <# } #> } @@ -81,7 +84,7 @@ namespace <#= Generator.Namespace #> { <# PushIndent ("\t\t"); foreach (var field in Class.Fields.Where (f => f.Access != Access.@private)) { var fieldName = CSharpLanguage.SafeIdentifier (field.Name); - WriteLine ("{0} {1} {2} {{", field.Access, CSharpLanguage.TypeName (field.Type), fieldName); #> + WriteLine ("{0} {1} {2} {{", field.Access, CSharpLanguage.TypeName (field.Type, CSharpLanguage.Context.Return), fieldName); #> get { return impl.<#= fieldName #> [Native]; } @@ -137,7 +140,7 @@ namespace <#= Generator.Namespace #> { <# PushIndent ("\t\t"); foreach (var prop in Class.Properties) { var propName = CSharpLanguage.SafeIdentifier (prop.Name); - var type = CSharpLanguage.TypeName (prop.Type); + var type = CSharpLanguage.TypeName (prop.Type, CSharpLanguage.Context.Return); Write (CurrentIndent + "public "); @@ -280,7 +283,7 @@ if (Class.BaseClasses.Count > 1) { #> <#+ private void WriteMethodHeader (Method method, string layoutClass, bool isNonPrimaryOverride, bool @protected) { - var returnType = CSharpLanguage.TypeName (method.ReturnType); + var returnType = CSharpLanguage.TypeName (method.ReturnType, CSharpLanguage.Context.Return); if (!isNonPrimaryOverride && method.IsVirtual) WriteLine ("[OverrideNative (\"{0}\")]", method.Name); @@ -320,7 +323,7 @@ private void WriteParameters (IList parameters, bool writeType, bool if (i != 0) Write (", "); - var type = CSharpLanguage.TypeName (parameters [i].Type); + var type = CSharpLanguage.TypeName (parameters [i].Type, CSharpLanguage.Context.Parameter); if (writeAttributes) { var mangleAs = parameters [i].Type.ToString (); @@ -330,11 +333,6 @@ private void WriteParameters (IList parameters, bool writeType, bool Write ("[ByVal] "); } - if (type.EndsWith ("&")) { - Write ("ref "); - type = CSharpLanguage.TypeName (type.TrimEnd ('&')); - } - if (writeType) { Write (type); Write (" "); @@ -364,4 +362,10 @@ private bool IsByVal (CppType t) !t.Modifiers.Contains (CppModifiers.Reference) && !t.Modifiers.Contains (CppModifiers.Array)); } +private bool IsByRef (CppType t) +{ + return ((t.ElementType != CppTypes.Class && t.ElementType != CppTypes.Struct) && + t.Modifiers.Contains (CppModifiers.Pointer) || + t.Modifiers.Contains (CppModifiers.Reference)); +} #> \ No newline at end of file diff --git a/src/generator/Templates/CSharp/CSharpLanguage.cs b/src/generator/Templates/CSharp/CSharpLanguage.cs index 8ff24a7c..7110cdd3 100644 --- a/src/generator/Templates/CSharp/CSharpLanguage.cs +++ b/src/generator/Templates/CSharp/CSharpLanguage.cs @@ -22,17 +22,23 @@ namespace Templates { "partial", "yield", "where" }; + public enum Context { + Generic, + Parameter, + Return + } + public static string SafeIdentifier (string proposedName) { return keywords.Contains (proposedName)? "@" + proposedName : proposedName; } - public static string TypeName (CppType t) + public static string TypeName (CppType t, Context context) { - return TypeName (Generator.CppTypeToManaged (t)); + return TypeName (Generator.CppTypeToManaged (t), context); } - public static string TypeName (string str) + public static string TypeName (string str, Context context) { switch (str) { case "System.Void": return "void"; @@ -53,6 +59,15 @@ namespace Templates { case "System.String": return "string"; } + if (str.EndsWith ("&")) { + if (context == Context.Parameter) + return "ref " + TypeName (str.TrimEnd ('&'), context); + if (context == Context.Return) + return TypeName (str.TrimEnd ('&'), context); + if (context == Context.Generic) + return "IntPtr"; + } + // we are using System by default var lastDot = str.LastIndexOf ('.'); if (str.StartsWith ("System") && lastDot == "System".Length) diff --git a/tests/MarshalingTests.cs b/tests/MarshalingTests.cs index a476b733..c060cad2 100644 --- a/tests/MarshalingTests.cs +++ b/tests/MarshalingTests.cs @@ -63,6 +63,13 @@ namespace Tests { var c1 = new Class (4); c1.CopyFromValue (null); } + + [Test] + public void TestByRefReturn () + { + var c1 = new Class (7); + Assert.AreEqual (7, c1.GetXRef ()); + } } diff --git a/tests/Native/MarshalingTests.h b/tests/Native/MarshalingTests.h index dc9ca969..5c310f73 100644 --- a/tests/Native/MarshalingTests.h +++ b/tests/Native/MarshalingTests.h @@ -67,6 +67,10 @@ public: int GetX () { return x; } + + int& GetXRef () { + return x; + } };