Skip to content

Commit

Permalink
CSharpSources: Dereference pointer variables (mono#1753)
Browse files Browse the repository at this point in the history
Dereference pointers when generating getters for pointer variables.
Otherwise, the managed instance would point to the pointer itself
rather than the object at the native instance's address.
  • Loading branch information
trungnt2910 committed Jul 21, 2023
1 parent 3978fb3 commit ce3d04a
Show file tree
Hide file tree
Showing 4 changed files with 48 additions and 0 deletions.
11 changes: 11 additions & 0 deletions src/Generator/Generators/CSharp/CSharpSources.cs
Expand Up @@ -1285,6 +1285,17 @@ private bool GenerateVariableGetter(Variable var)
};
ctx.PushMarshalKind(MarshalKind.ReturnVariableArray);

if (var.Type.Desugar().IsPointer())
{
var pointerType = var.Type.Desugar() as PointerType;
while (pointerType != null && !pointerType.Pointee.Desugar().IsPrimitiveType(PrimitiveType.Char))
{
ptr = $"*{ptr}";
pointerType = pointerType.Pointee.Desugar() as PointerType;
}
ptr = $"(IntPtr*)({ptr})";
}

var arrayType = var.Type.Desugar() as ArrayType;
var isRefTypeArray = arrayType != null && var.Namespace is Class context && context.IsRefType;
var elementType = arrayType?.Type.Desugar();
Expand Down
7 changes: 7 additions & 0 deletions tests/dotnet/CSharp/CSharp.Tests.cs
Expand Up @@ -1988,4 +1988,11 @@ public void TestCallByValueCppToCSharpPointer()
Assert.That(RuleOfThreeTester.CopyConstructorCalls, Is.EqualTo(0));
Assert.That(RuleOfThreeTester.CopyAssignmentCalls, Is.EqualTo(0));
}

[Test]
public void TestPointerToClass()
{
Assert.IsTrue(CSharp.CSharp.PointerToClass.IsDefaultInstance);
Assert.IsTrue(CSharp.CSharp.PointerToClass.IsValid);
}
}
19 changes: 19 additions & 0 deletions tests/dotnet/CSharp/CSharp.cpp
Expand Up @@ -1772,3 +1772,22 @@ void CallCallByValueInterfacePointer(CallByValueInterface* interface)
RuleOfThreeTester value;
interface->CallByPointer(&value);
}

static PointerTester internalPointerTesterInstance;

PointerTester::PointerTester()
{
a = 0;
}

bool PointerTester::IsDefaultInstance()
{
return this == &internalPointerTesterInstance;
}

bool PointerTester::IsValid()
{
return a == 0;
}

PointerTester* PointerToClass = &internalPointerTesterInstance;
11 changes: 11 additions & 0 deletions tests/dotnet/CSharp/CSharp.h
Expand Up @@ -1592,3 +1592,14 @@ struct DLL_API CallByValueInterface {
void DLL_API CallCallByValueInterfaceValue(CallByValueInterface*);
void DLL_API CallCallByValueInterfaceReference(CallByValueInterface*);
void DLL_API CallCallByValueInterfacePointer(CallByValueInterface*);

class DLL_API PointerTester
{
int a;
public:
PointerTester();
bool IsDefaultInstance();
bool IsValid();
};

DLL_API extern PointerTester* PointerToClass;

0 comments on commit ce3d04a

Please sign in to comment.