From 261473cef8755e105531d53524f0b2c1c99e63ed Mon Sep 17 00:00:00 2001 From: Dimitar Dobrev Date: Thu, 30 Oct 2014 23:08:16 +0200 Subject: [PATCH] Extended the support for fixed arrays to the C++/CLI back-end. Signed-off-by: Dimitar Dobrev --- src/Generator/Generators/CLI/CLIMarshal.cs | 36 +++++++++++++++++-- .../Generators/CLI/CLISourcesTemplate.cs | 28 ++++++++------- tests/Basic/Basic.Tests.cs | 10 ++++++ tests/Basic/Basic.h | 1 + tests/CSharpTemp/CSharpTemp.Tests.cs | 10 ------ tests/CSharpTemp/CSharpTemp.h | 1 - 6 files changed, 61 insertions(+), 25 deletions(-) diff --git a/src/Generator/Generators/CLI/CLIMarshal.cs b/src/Generator/Generators/CLI/CLIMarshal.cs index b4513956..537e11f9 100644 --- a/src/Generator/Generators/CLI/CLIMarshal.cs +++ b/src/Generator/Generators/CLI/CLIMarshal.cs @@ -45,7 +45,20 @@ namespace CppSharp.Generators.CLI switch (array.SizeType) { case ArrayType.ArraySize.Constant: - Context.Return.Write("nullptr"); + var supportBefore = Context.SupportBefore; + string value = Generator.GeneratedIdentifier("array"); + supportBefore.WriteLine("cli::array<{0}>^ {1} = nullptr;", array.Type, value, array.Size); + supportBefore.WriteLine("if ({0} != 0)", Context.ReturnVarName); + supportBefore.WriteStartBraceIndent(); + supportBefore.WriteLine("{0} = gcnew cli::array<{1}>({2});", value, array.Type, array.Size); + supportBefore.WriteLine("for (int i = 0; i < {0}; i++)", array.Size); + if (array.Type.IsPointerToPrimitiveType(PrimitiveType.Void)) + supportBefore.WriteLineIndent("{0}[i] = new ::System::IntPtr({1}[i]);", + value, Context.ReturnVarName); + else + supportBefore.WriteLineIndent("{0}[i] = {1}[i];", value, Context.ReturnVarName); + supportBefore.WriteCloseBraceIndent(); + Context.Return.Write(value); break; case ArrayType.ArraySize.Variable: Context.Return.Write("nullptr"); @@ -412,7 +425,26 @@ namespace CppSharp.Generators.CLI public override bool VisitArrayType(ArrayType array, TypeQualifiers quals) { - return false; + if (!VisitType(array, quals)) + return false; + + switch (array.SizeType) + { + case ArrayType.ArraySize.Constant: + var supportBefore = Context.SupportBefore; + supportBefore.WriteLine("if ({0} != nullptr)", Context.ArgName); + supportBefore.WriteStartBraceIndent(); + supportBefore.WriteLine("for (int i = 0; i < {0}; i++)", array.Size); + supportBefore.WriteLineIndent("{0}[i] = {1}[i]{2};", + Context.ReturnVarName, Context.ArgName, + array.Type.IsPointerToPrimitiveType(PrimitiveType.Void) ? ".ToPointer()" : string.Empty); + supportBefore.WriteCloseBraceIndent(); + break; + default: + Context.Return.Write("null"); + break; + } + return true; } public override bool VisitFunctionType(FunctionType function, TypeQualifiers quals) diff --git a/src/Generator/Generators/CLI/CLISourcesTemplate.cs b/src/Generator/Generators/CLI/CLISourcesTemplate.cs index df6abf43..e9a9db43 100644 --- a/src/Generator/Generators/CLI/CLISourcesTemplate.cs +++ b/src/Generator/Generators/CLI/CLISourcesTemplate.cs @@ -391,33 +391,37 @@ namespace CppSharp.Generators.CLI QualifiedType = new QualifiedType(type) }; + string variable; + if (decl is Variable) + variable = string.Format("::{0}::{1}", + @class.QualifiedOriginalName, decl.OriginalName); + else + variable = string.Format("((::{0}*)NativePtr)->{1}", + @class.QualifiedOriginalName, decl.OriginalName); + var ctx = new MarshalContext(Driver) { Parameter = param, ArgName = param.Name, + ReturnVarName = variable }; var marshal = new CLIMarshalManagedToNativePrinter(ctx); param.Visit(marshal); - string variable; - if (decl is Variable) - variable = string.Format("::{0}::{1}", - @class.QualifiedOriginalName, decl.OriginalName); - else - variable = string.Format("((::{0}*)NativePtr)->{1}", - @class.QualifiedOriginalName, decl.OriginalName); - if (isIndexer) variable += string.Format("({0})", indexParameter.Name); if (!string.IsNullOrWhiteSpace(marshal.Context.SupportBefore)) Write(marshal.Context.SupportBefore); - if (isIndexer && decl.Type.IsPointer()) - WriteLine("*({0}) = {1};", variable, marshal.Context.Return); - else - WriteLine("{0} = {1};", variable, marshal.Context.Return); + if (marshal.Context.Return.StringBuilder.Length > 0) + { + if (isIndexer && decl.Type.IsPointer()) + WriteLine("*({0}) = {1};", variable, marshal.Context.Return); + else + WriteLine("{0} = {1};", variable, marshal.Context.Return); + } } WriteCloseBraceIndent(); diff --git a/tests/Basic/Basic.Tests.cs b/tests/Basic/Basic.Tests.cs index 4fe5dfc2..38e9343e 100644 --- a/tests/Basic/Basic.Tests.cs +++ b/tests/Basic/Basic.Tests.cs @@ -442,5 +442,15 @@ public class BasicTests : GeneratorTestFixture { new TestDelegates().MarshalUnattributedDelegate(i => i); } + + [Test] + public void TestFixedArrays() + { + var foo = new Foo(); + var array = new[] { 1, 2, 3 }; + foo.fixedArray = array; + for (int i = 0; i < foo.fixedArray.Length; i++) + Assert.That(array[i], Is.EqualTo(foo.fixedArray[i])); + } } \ No newline at end of file diff --git a/tests/Basic/Basic.h b/tests/Basic/Basic.h index 2230e4d6..9c9d9ce6 100644 --- a/tests/Basic/Basic.h +++ b/tests/Basic/Basic.h @@ -29,6 +29,7 @@ public: int A; float B; IgnoredType ignoredType; + int fixedArray[3]; const char* GetANSI(); // TODO: VC++ does not support char16 diff --git a/tests/CSharpTemp/CSharpTemp.Tests.cs b/tests/CSharpTemp/CSharpTemp.Tests.cs index b26ab610..e8f95159 100644 --- a/tests/CSharpTemp/CSharpTemp.Tests.cs +++ b/tests/CSharpTemp/CSharpTemp.Tests.cs @@ -31,16 +31,6 @@ public class CSharpTempTests : GeneratorTestFixture BindingFlags.Instance | BindingFlags.NonPublic), Is.Not.Null); } - [Test] - public void TestFixedArrays() - { - Qux qux = new Qux((Foo) null); - var array = new[] { 1, 2, 3 }; - qux.Array = array; - for (int i = 0; i < qux.Array.Length; i++) - Assert.That(array[i], Is.EqualTo(qux.Array[i])); - } - [Test] public void TestMultipleInheritance() { diff --git a/tests/CSharpTemp/CSharpTemp.h b/tests/CSharpTemp/CSharpTemp.h index f2d8c535..0a51445e 100644 --- a/tests/CSharpTemp/CSharpTemp.h +++ b/tests/CSharpTemp/CSharpTemp.h @@ -20,7 +20,6 @@ public: Qux(); Qux(Foo foo); int farAwayFunc() const; - int array[3]; void obsolete(); };