Browse Source

Fix Value Type String Member Invalid Codegen (#1778)

* Fix code generation

* Generate exception on broken struct set op

* Remove redundant usings
pull/1782/head
Stefan 3 years ago committed by GitHub
parent
commit
03874e743f
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
  1. 22
      src/Generator/Types/Std/Stdlib.CSharp.cs
  2. 1
      tests/dotnet/CSharp/CSharp.CSharp.csproj
  3. 14
      tests/dotnet/CSharp/CSharp.Tests.cs
  4. 9
      tests/dotnet/CSharp/CSharp.h

22
src/Generator/Types/Std/Stdlib.CSharp.cs

@ -1,3 +1,4 @@ @@ -1,3 +1,4 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Runtime.InteropServices;
@ -6,6 +7,7 @@ using CppSharp.AST; @@ -6,6 +7,7 @@ using CppSharp.AST;
using CppSharp.AST.Extensions;
using CppSharp.Generators;
using CppSharp.Generators.CSharp;
using Type = CppSharp.AST.Type;
namespace CppSharp.Types.Std
{
@ -145,7 +147,7 @@ namespace CppSharp.Types.Std @@ -145,7 +147,7 @@ namespace CppSharp.Types.Std
// would be really helpful to have ctx hold a Decl property representing the
// "appropriate" Decl when we get here. When MarshalKind == NativeField, Decl would
// be set to the Field we're operating on.
var fieldName = ctx.ReturnVarName.Substring(ctx.ReturnVarName.LastIndexOf("->") + 2);
var fieldName = ctx.ReturnVarName[Math.Max(ctx.ReturnVarName.LastIndexOf('.') + 1, ctx.ReturnVarName.LastIndexOf("->") + 2)..];
ctx.Before.WriteLine($"if (__{fieldName}_OwnsNativeMemory)");
ctx.Before.WriteLineIndent($"Marshal.FreeHGlobal({ctx.ReturnVarName});");
@ -326,10 +328,24 @@ namespace CppSharp.Types.Std @@ -326,10 +328,24 @@ namespace CppSharp.Types.Std
var assign = basicString.Methods.First(m => m.OriginalName == "assign");
if (ctx.MarshalKind == MarshalKind.NativeField)
{
string var;
if (ctx.ReturnVarName.LastIndexOf('.') > ctx.ReturnVarName.LastIndexOf("->"))
{
ctx.Before.WriteLine("throw new NotImplementedException(\"This method cannot currently be called because it would " +
"leave the object in an invalid state. See https://github.com/mono/CppSharp/issues/1777\");");
var = Generator.GeneratedIdentifier(ctx.ArgName);
ctx.Before.WriteLine($"fixed (void* {var} = &{ctx.ReturnVarName})");
ctx.Before.WriteOpenBraceAndIndent();
ctx.HasCodeBlock = true;
}
else
{
var = $"&{ctx.ReturnVarName}";
}
ctx.Return.Write($@"{qualifiedBasicString}Extensions.{
Helpers.InternalStruct}.{assign.Name}(new {
typePrinter.IntPtrType}(&{
ctx.ReturnVarName}), ");
typePrinter.IntPtrType}({var}), ");
if (ctx.Parameter.Type.IsTemplateParameterType())
ctx.Return.Write("(string) (object) ");
ctx.Return.Write($"{ctx.Parameter.Name})");

1
tests/dotnet/CSharp/CSharp.CSharp.csproj

@ -1,6 +1,7 @@ @@ -1,6 +1,7 @@
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<NoWarn>0108</NoWarn>
<LangVersion>10</LangVersion>
</PropertyGroup>
<ItemGroup>
<Compile Include="CSharpPartialMethods.cs" />

14
tests/dotnet/CSharp/CSharp.Tests.cs

@ -3,7 +3,6 @@ using System.Collections.Generic; @@ -3,7 +3,6 @@ using System.Collections.Generic;
using System.Linq;
using System.Reflection;
using System.Runtime.InteropServices;
using System.Text;
using CSharp;
using NUnit.Framework;
@ -2024,4 +2023,17 @@ public unsafe class CSharpTests @@ -2024,4 +2023,17 @@ public unsafe class CSharpTests
Assert.That(new CSharp.Optional<IntPtr>(IntPtr.MaxValue) == new CSharp.Optional<IntPtr>(IntPtr.MaxValue));
Assert.That(new CSharp.Optional<IntPtr>(IntPtr.MaxValue) == IntPtr.MaxValue);
}
[Test]
[Ignore("https://github.com/mono/CppSharp/issues/1730")]
public void TestString()
{
var test = new CSharp.ValueType();
Assert.AreEqual(string.Empty, test.StringMember);
Assert.AreEqual(null, test.CharPtrMember);
test.StringMember = "test";
test.CharPtrMember = "test2";
Assert.AreEqual("test", test.StringMember);
Assert.AreEqual("test2", test.CharPtrMember);
}
}

9
tests/dotnet/CSharp/CSharp.h

@ -1641,3 +1641,12 @@ public: @@ -1641,3 +1641,12 @@ public:
// We just need a method that uses various instantiations of Optional.
inline void DLL_API InstantiateOptionalTemplate(Optional<unsigned int>, Optional<std::string>,
Optional<TestComparison>, Optional<char*>, Optional<UnionTester>) { }
CS_VALUE_TYPE class DLL_API ValueType {
public:
// Parameterless ctors are currently not generated for value types.
ValueType(int) { }
std::string string_member;
const char* char_ptr_member;
};

Loading…
Cancel
Save