Browse Source

Fix the passing of references to pointers in C#

Signed-off-by: Dimitar Dobrev <dpldobrev@protonmail.com>
bug-pass-const-char-star-no-copy
Dimitar Dobrev 6 years ago
parent
commit
62fc6f90d9
  1. 23
      src/Generator/Generators/CSharp/CSharpMarshal.cs
  2. 3
      src/Generator/Generators/CSharp/CSharpSources.cs
  3. 22
      tests/CSharp/CSharp.Tests.cs
  4. 5
      tests/CSharp/CSharp.cpp
  5. 1
      tests/CSharp/CSharp.h

23
src/Generator/Generators/CSharp/CSharpMarshal.cs

@ -587,25 +587,34 @@ namespace CppSharp.Generators.CSharp @@ -587,25 +587,34 @@ namespace CppSharp.Generators.CSharp
return true;
}
string arg = Generator.GeneratedIdentifier(Context.ArgName);
if (pointee.TryGetClass(out Class @class) && @class.IsValueType)
{
if (Context.Parameter.Usage == ParameterUsage.Out)
{
var qualifiedIdentifier = (@class.OriginalClass ?? @class).Visit(typePrinter);
Context.Before.WriteLine("var {0} = new {1}.{2}();",
Generator.GeneratedIdentifier(Context.ArgName), qualifiedIdentifier,
Helpers.InternalStruct);
arg, qualifiedIdentifier, Helpers.InternalStruct);
}
else
{
Context.Before.WriteLine("var {0} = {1}.{2};",
Generator.GeneratedIdentifier(Context.ArgName),
Context.Parameter.Name,
Helpers.InstanceIdentifier);
arg, Context.Parameter.Name, Helpers.InstanceIdentifier);
}
Context.Return.Write("new global::System.IntPtr(&{0})",
Generator.GeneratedIdentifier(Context.ArgName));
Context.Return.Write($"new global::System.IntPtr(&{arg})");
return true;
}
if (pointee.IsPointerTo(out Type type) &&
type.Desugar().TryGetClass(out Class c))
{
pointer.QualifiedPointee.Visit(this);
Context.Before.WriteLine($"var {arg} = {Context.Return};");
Context.Return.StringBuilder.Clear();
Context.Return.Write($"new global::System.IntPtr(&{arg})");
return true;
}

3
src/Generator/Generators/CSharp/CSharpSources.cs

@ -1037,7 +1037,8 @@ namespace CppSharp.Generators.CSharp @@ -1037,7 +1037,8 @@ namespace CppSharp.Generators.CSharp
},
ParameterIndex = function.Parameters.Count(
p => p.Kind != ParameterKind.IndirectReturnType),
ReturnType = new QualifiedType(type)
ReturnType = new QualifiedType(type),
ArgName = "value"
};
var marshal = new CSharpMarshalManagedToNativePrinter(ctx);
type.Visit(marshal);

22
tests/CSharp/CSharp.Tests.cs

@ -94,10 +94,6 @@ public unsafe class CSharpTests : GeneratorTestFixture @@ -94,10 +94,6 @@ public unsafe class CSharpTests : GeneratorTestFixture
{
}
int value = 5;
IntPtr intPtr = CSharp.CSharp.RValueReferenceToPointer((void**) &value);
Assert.That((int) intPtr, Is.EqualTo(value));
#pragma warning restore 0168
#pragma warning restore 0219
}
@ -1276,6 +1272,24 @@ public unsafe class CSharpTests : GeneratorTestFixture @@ -1276,6 +1272,24 @@ public unsafe class CSharpTests : GeneratorTestFixture
Assert.That(CSharp.CSharp.TakeConstCharStarRef("Test"), Is.EqualTo("Test"));
}
[Test]
public void TestRValueReferenceToPointer()
{
int value = 5;
IntPtr intPtr = CSharp.CSharp.RValueReferenceToPointer((void**) &value);
Assert.That((int) intPtr, Is.EqualTo(value));
}
[Test]
public void TakeRefToPointerToObject()
{
using (Foo foo = new Foo { A = 25 })
{
Foo returnedFoo = CSharp.CSharp.TakeRefToPointerToObject(foo);
Assert.That(returnedFoo.A, Is.EqualTo(foo.A));
}
}
[Test]
public void TestImplicitConversionToString()
{

5
tests/CSharp/CSharp.cpp

@ -1623,6 +1623,11 @@ const void*& rValueReferenceToPointer(void*&& v) @@ -1623,6 +1623,11 @@ const void*& rValueReferenceToPointer(void*&& v)
return (const void*&) v;
}
const Foo* takeRefToPointerToObject(const Foo*& foo)
{
return foo;
}
boolean_t takeTypemapTypedefParam(boolean_t b)
{
return b;

1
tests/CSharp/CSharp.h

@ -1325,6 +1325,7 @@ DLL_API char* returnCharPointer(); @@ -1325,6 +1325,7 @@ DLL_API char* returnCharPointer();
DLL_API char* takeConstCharRef(const char& c);
DLL_API const char*& takeConstCharStarRef(const char*& c);
DLL_API const void*& rValueReferenceToPointer(void*&& v);
DLL_API const Foo* takeRefToPointerToObject(const Foo*& foo);
struct {
struct {

Loading…
Cancel
Save