Skip to content

Commit

Permalink
Fix code generation
Browse files Browse the repository at this point in the history
  • Loading branch information
Saalvage committed Oct 19, 2023
1 parent 19aa51b commit 3fd7ee4
Show file tree
Hide file tree
Showing 4 changed files with 36 additions and 3 deletions.
19 changes: 16 additions & 3 deletions src/Generator/Types/Std/Stdlib.CSharp.cs
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Runtime.InteropServices;
Expand All @@ -6,6 +7,7 @@
using CppSharp.AST.Extensions;
using CppSharp.Generators;
using CppSharp.Generators.CSharp;
using Type = CppSharp.AST.Type;

namespace CppSharp.Types.Std
{
Expand Down Expand Up @@ -145,7 +147,7 @@ public override void CSharpMarshalToNative(CSharpMarshalContext ctx)
// 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});");
Expand Down Expand Up @@ -326,10 +328,21 @@ public override void CSharpMarshalToNative(CSharpMarshalContext ctx)
var assign = basicString.Methods.First(m => m.OriginalName == "assign");
if (ctx.MarshalKind == MarshalKind.NativeField)
{
string var;
if (ctx.ReturnVarName.LastIndexOf('.') > ctx.ReturnVarName.LastIndexOf("->"))
{
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.IsTemplate())
ctx.Return.Write("(string) (object) ");
ctx.Return.Write($"{ctx.Parameter.Name})");
Expand Down
1 change: 1 addition & 0 deletions tests/dotnet/CSharp/CSharp.CSharp.csproj
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<NoWarn>0108</NoWarn>
<LangVersion>10</LangVersion>
</PropertyGroup>
<ItemGroup>
<Compile Include="CSharpPartialMethods.cs" />
Expand Down
13 changes: 13 additions & 0 deletions tests/dotnet/CSharp/CSharp.Tests.cs
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@
using System.Text;
using CSharp;
using NUnit.Framework;
using ValueType = CSharp.ValueType;

[TestFixture]
public unsafe class CSharpTests
Expand Down Expand Up @@ -2024,4 +2025,16 @@ public void TestOptionalIntPtr()
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]
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);
}
}
6 changes: 6 additions & 0 deletions tests/dotnet/CSharp/CSharp.h
Original file line number Diff line number Diff line change
Expand Up @@ -1641,3 +1641,9 @@ class Optional {
// 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 value_type {
public:
std::string string_member;
const char* char_ptr_member;
};

0 comments on commit 3fd7ee4

Please sign in to comment.