From 66bbc388e16368781a6bfe4c79893781501a5357 Mon Sep 17 00:00:00 2001 From: Alin Gherman Date: Fri, 24 Feb 2017 01:28:31 +0100 Subject: [PATCH 1/2] Let the marshal determine the size of the structure Signed-off-by: Alin Gherman --- src/Generator/Generators/CSharp/CSharpSources.cs | 11 +++++++---- 1 file changed, 7 insertions(+), 4 deletions(-) diff --git a/src/Generator/Generators/CSharp/CSharpSources.cs b/src/Generator/Generators/CSharp/CSharpSources.cs index 94522128..d88c846b 100644 --- a/src/Generator/Generators/CSharp/CSharpSources.cs +++ b/src/Generator/Generators/CSharp/CSharpSources.cs @@ -2126,7 +2126,7 @@ namespace CppSharp.Generators.CSharp copyCtorMethod.IsGenerated) { // Allocate memory for a new native object and call the ctor. - WriteLine("var ret = Marshal.AllocHGlobal({0});", @class.Layout.Size); + WriteLine("var ret = Marshal.AllocHGlobal(Marshal.SizeOf(sizeof({0})));", @internal); TypePrinter.PushContext(TypePrinterContextKind.Native); WriteLine($"{@class.Visit(TypePrinter)}.{GetFunctionNativeIdentifier(copyCtorMethod)}(ret, new global::System.IntPtr(&native));", @class.Visit(TypePrinter), @@ -2136,7 +2136,7 @@ namespace CppSharp.Generators.CSharp } else { - WriteLine("var ret = Marshal.AllocHGlobal({0});", @class.Layout.Size); + WriteLine("var ret = Marshal.AllocHGlobal(Marshal.SizeOf(sizeof({0})));", @internal); WriteLine("*({0}*) ret = native;", @internal); WriteLine("return ret.ToPointer();"); } @@ -2577,8 +2577,11 @@ namespace CppSharp.Generators.CSharp private void GenerateClassConstructor(Method method, Class @class) { - WriteLine("{0} = Marshal.AllocHGlobal({1});", Helpers.InstanceIdentifier, - @class.Layout.Size); + TypePrinter.PushContext(TypePrinterContextKind.Native); + var @internal = (@class.IsAbstractImpl ? @class.BaseClass : @class).Visit(TypePrinter); + TypePrinter.PopContext(); + WriteLine("{0} = Marshal.AllocHGlobal(Marshal.SizeOf(sizeof({1})));", Helpers.InstanceIdentifier, + @internal); WriteLine("{0} = true;", Helpers.OwnsNativeInstanceIdentifier); WriteLine("NativeToManagedMap[{0}] = this;", Helpers.InstanceIdentifier); From 6e42ef36a68ed81c1371db6303d74e82438033d0 Mon Sep 17 00:00:00 2001 From: Alin Gherman Date: Fri, 24 Feb 2017 03:30:13 +0100 Subject: [PATCH 2/2] Add the GenerateSequentialLayout option Signed-off-by: Alin Gherman --- .../Generators/CSharp/CSharpSources.cs | 20 ++++++++++++++++--- src/Generator/Options.cs | 1 + 2 files changed, 18 insertions(+), 3 deletions(-) diff --git a/src/Generator/Generators/CSharp/CSharpSources.cs b/src/Generator/Generators/CSharp/CSharpSources.cs index d88c846b..6a0d12b6 100644 --- a/src/Generator/Generators/CSharp/CSharpSources.cs +++ b/src/Generator/Generators/CSharp/CSharpSources.cs @@ -561,8 +561,15 @@ namespace CppSharp.Generators.CSharp public void GenerateClassInternals(Class @class) { PushBlock(CSharpBlockKind.InternalsClass); - WriteLine("[StructLayout(LayoutKind.Explicit, Size = {0})]", - @class.Layout.Size); + if (Options.GenerateSequentialLayout) + { + WriteLine("[StructLayout(LayoutKind.Sequential)]"); + } + else + { + WriteLine("[StructLayout(LayoutKind.Explicit, Size = {0})]", + @class.Layout.Size); + } GenerateClassInternalHead(@class); WriteStartBraceIndent(); @@ -772,7 +779,14 @@ namespace CppSharp.Generators.CSharp PushBlock(CSharpBlockKind.Field); - WriteLine("[FieldOffset({0})]", field.Offset); + if (Options.GenerateSequentialLayout) + { + // For the sequential layout there is no need to set an offset + } + else + { + WriteLine("[FieldOffset({0})]", field.Offset); + } TypePrinter.PushMarshalKind(MarshalKind.NativeField); var fieldTypePrinted = field.QualifiedType.CSharpType(TypePrinter); diff --git a/src/Generator/Options.cs b/src/Generator/Options.cs index 9325003d..df2b9ba2 100644 --- a/src/Generator/Options.cs +++ b/src/Generator/Options.cs @@ -161,6 +161,7 @@ namespace CppSharp public bool OutputInteropIncludes; public bool GenerateFunctionTemplates; public bool GenerateInternalImports; + public bool GenerateSequentialLayout; public bool UseHeaderDirectories; ///