From fb481baf7d47a3076b09a226bf690f094fd622e0 Mon Sep 17 00:00:00 2001 From: triton Date: Sun, 18 Aug 2013 19:12:45 +0100 Subject: [PATCH] Fixed return of structures by value in C# backend similarly to the CLI backend by using copy constructors if the class has any non-trivial ones, or just copying memory directly if the class only has trivial ones. --- .../Generators/CSharp/CSharpMarshal.cs | 34 +++++++++++++++++++ 1 file changed, 34 insertions(+) diff --git a/src/Generator/Generators/CSharp/CSharpMarshal.cs b/src/Generator/Generators/CSharp/CSharpMarshal.cs index 083023ae..545cd683 100644 --- a/src/Generator/Generators/CSharp/CSharpMarshal.cs +++ b/src/Generator/Generators/CSharp/CSharpMarshal.cs @@ -1,5 +1,6 @@ using System; using System.Collections.Generic; +using System.Linq; using CppSharp.AST; using CppSharp.Types; using Type = CppSharp.AST.Type; @@ -208,6 +209,39 @@ namespace CppSharp.Generators.CSharp instance = string.Format("new global::System.IntPtr(&{0})", instance); } + if (@class.IsRefType) + { + var instanceName = Helpers.GeneratedIdentifier("instance"); + + // Allocate memory for a new native object and call the ctor. + Context.SupportBefore.WriteLine("var {0} = Marshal.AllocHGlobal({1});", + instanceName, @class.Layout.Size); + + if (@class.HasNonTrivialCopyConstructor) + { + // Find a valid copy constructor overload. + var copyCtorMethod = @class.Methods.FirstOrDefault(method => + method.IsCopyConstructor); + + if (copyCtorMethod == null) + throw new NotSupportedException("Expected a valid copy constructor"); + + // Call the copy constructor. + Context.SupportBefore.WriteLine("{0}.Internal.{1}({2}, new global::System.IntPtr(&{3}));", + @class.QualifiedName, + CSharpTextTemplate.GetFunctionNativeIdentifier(copyCtorMethod), + instanceName, instance); + } + else + { + Context.SupportBefore.WriteLine( + "CppSharp.Runtime.Helpers.memcpy({0}, new IntPtr(&{1}), new UIntPtr({2}));", + instanceName, instance, @class.Layout.Size); + } + + instance = instanceName; + } + Context.Return.Write("new {0}({1})", QualifiedIdentifier(@class), instance);