From aa079c3222ec01e62d0865523af699033db31786 Mon Sep 17 00:00:00 2001 From: Dimitar Dobrev Date: Mon, 16 Jan 2017 22:46:12 +0200 Subject: [PATCH] Added setters to non-const static fields (variables) in the C# end. Fixes https://github.com/mono/CppSharp/issues/545. --- .../Generators/CSharp/CSharpMarshal.cs | 6 ++- .../Generators/CSharp/CSharpSources.cs | 53 +++++++++++++++---- tests/Common/Common.Tests.cs | 8 +++ tests/Common/Common.h | 2 + 4 files changed, 58 insertions(+), 11 deletions(-) diff --git a/src/Generator/Generators/CSharp/CSharpMarshal.cs b/src/Generator/Generators/CSharp/CSharpMarshal.cs index 868f4efa..4b1a1438 100644 --- a/src/Generator/Generators/CSharp/CSharpMarshal.cs +++ b/src/Generator/Generators/CSharp/CSharpMarshal.cs @@ -14,7 +14,8 @@ namespace CppSharp.Generators.CSharp NativeField, GenericDelegate, DefaultExpression, - VTableReturnValue + VTableReturnValue, + Variable } public class CSharpMarshalContext : MarshalContext @@ -591,7 +592,8 @@ namespace CppSharp.Generators.CSharp typePrinter.PopContext(); } if (marshalAsString && (Context.Kind == CSharpMarshalKind.NativeField || - Context.Kind == CSharpMarshalKind.VTableReturnValue)) + Context.Kind == CSharpMarshalKind.VTableReturnValue || + Context.Kind == CSharpMarshalKind.Variable)) Context.Return.Write(MarshalStringToUnmanaged(Context.Parameter.Name)); else Context.Return.Write(Context.Parameter.Name); diff --git a/src/Generator/Generators/CSharp/CSharpSources.cs b/src/Generator/Generators/CSharp/CSharpSources.cs index ca420b54..ca4bd4ae 100644 --- a/src/Generator/Generators/CSharp/CSharpSources.cs +++ b/src/Generator/Generators/CSharp/CSharpSources.cs @@ -841,11 +841,6 @@ namespace CppSharp.Generators.CSharp Class @class, bool isAbstract = false, Property property = null) where T : Declaration, ITypedDecl { - if (!(decl is Function || decl is Field) ) - { - return; - } - PushBlock(CSharpBlockKind.Method); Write("set"); @@ -905,9 +900,8 @@ namespace CppSharp.Generators.CSharp GenerateInternalFunctionCall(function, new List { param }); } } - WriteCloseBraceIndent(); } - else + else if (decl is Field) { var field = decl as Field; if (WrapSetterArrayOfPointers(decl.Name, field.Type)) @@ -957,9 +951,49 @@ namespace CppSharp.Generators.CSharp if ((arrayType != null && @class.IsValueType) || ctx.HasCodeBlock) WriteCloseBraceIndent(); + } + else if (decl is Variable) + { + NewLine(); + WriteStartBraceIndent(); + var var = decl as Variable; - WriteCloseBraceIndent(); + TypePrinter.PushContext(CSharpTypePrinterContextKind.Native); + + var location = $@"CppSharp.SymbolResolver.ResolveSymbol(""{ + GetLibraryOf(decl)}"", ""{var.Mangled}"")"; + + string ptr = Generator.GeneratedIdentifier("ptr"); + var arrayType = decl.Type as ArrayType; + var isRefTypeArray = arrayType != null && @class != null && @class.IsRefType; + if (isRefTypeArray) + WriteLine($@"var {ptr} = { + (arrayType.Type.IsPrimitiveType(PrimitiveType.Char) && + arrayType.QualifiedType.Qualifiers.IsConst ? + string.Empty : "(byte*)")}{location};"); + else + WriteLine($"var {ptr} = ({var.Type}*){location};"); + + TypePrinter.PopContext(); + + ctx.Kind = CSharpMarshalKind.Variable; + ctx.ReturnType = new QualifiedType(var.Type); + + var marshal = new CSharpMarshalManagedToNativePrinter(ctx); + decl.CSharpMarshalToNative(marshal); + + if (!string.IsNullOrWhiteSpace(marshal.Context.SupportBefore)) + Write(marshal.Context.SupportBefore); + + if (ctx.HasCodeBlock) + PushIndent(); + + WriteLine($"*{ptr} = {marshal.Context.Return};", marshal.Context.Return); + + if (ctx.HasCodeBlock) + WriteCloseBraceIndent(); } + WriteCloseBraceIndent(); PopBlock(NewLineKind.BeforeNextBlock); } @@ -1371,7 +1405,8 @@ namespace CppSharp.Generators.CSharp GeneratePropertyGetter(variable.QualifiedType, variable, @class); - if (!variable.QualifiedType.Qualifiers.IsConst) + if (!variable.QualifiedType.Qualifiers.IsConst && + !(variable.Type.Desugar() is ArrayType)) GeneratePropertySetter(variable, @class); WriteCloseBraceIndent(); diff --git a/tests/Common/Common.Tests.cs b/tests/Common/Common.Tests.cs index 96b1edde..0ac6018b 100644 --- a/tests/Common/Common.Tests.cs +++ b/tests/Common/Common.Tests.cs @@ -648,6 +648,14 @@ public class CommonTests : GeneratorTestFixture } } + [Test] + public void TestStaticFields() + { + Assert.That(Foo.readWrite, Is.EqualTo(15)); + Foo.readWrite = 25; + Assert.That(Foo.readWrite, Is.EqualTo(25)); + } + [Test, Ignore("We need symbols for std::string to invoke and auto-compilation of exported templates is not added yet.")] public void TestStdString() { diff --git a/tests/Common/Common.h b/tests/Common/Common.h index 39c1c039..7ad8f6c2 100644 --- a/tests/Common/Common.h +++ b/tests/Common/Common.h @@ -49,6 +49,7 @@ public: void* ptr; static const int unsafe; static const char charArray[]; + static int readWrite; const char* GetANSI(); @@ -68,6 +69,7 @@ public: // HACK: do not move these to the cpp - C++/CLI is buggy and cannot link static fields initialised in the cpp const int Foo::unsafe = 10; +int Foo::readWrite = 15; const char Foo::charArray[] = "abc"; struct DLL_API Bar