Browse Source

bug fix: When generating the get accessor for a field composed of an embedded array of structs use __GetOrCreateInstance to initialize the managed array wrapper rather than __CreateInstance so that __Instance holds a pointer to the memory allocated for the array in the outer struct rather than an independent copy of that memory.

Added a test.

TODO: once allocated, we may want to cache the managed array. Does this
issue exist in other generators as well?
pull/1612/head
Joe Hull 4 years ago committed by João Matos
parent
commit
eb0d4c15f1
  1. 4
      src/Generator/Generators/CSharp/CSharpMarshal.cs
  2. 1
      src/Generator/Generators/CodeGenerator.cs
  3. 16
      tests/CSharp/CSharp.Tests.cs
  4. 2
      tests/CSharp/CSharp.h

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

@ -91,8 +91,8 @@ namespace CppSharp.Generators.CSharp @@ -91,8 +91,8 @@ namespace CppSharp.Generators.CSharp
{
if (arrayType == finalArrayType)
supportBefore.WriteLineIndent(
"{0}[i] = {1}.{2}(*(({1}.{3}*)&({4}[i * sizeof({1}.{3})])));",
value, array.Type, Helpers.CreateInstanceIdentifier,
"{0}[i] = {1}.{2}((IntPtr)(({1}.{3}*)&({4}[i * sizeof({1}.{3})])), true, true);",
value, array.Type, Helpers.GetOrCreateInstanceIdentifier,
Helpers.InternalStruct, Context.ReturnVarName);
else
supportBefore.WriteLineIndent(

1
src/Generator/Generators/CodeGenerator.cs

@ -1301,6 +1301,7 @@ namespace CppSharp.Generators @@ -1301,6 +1301,7 @@ namespace CppSharp.Generators
public static readonly string OwnsNativeInstanceIdentifier = Generator.GeneratedIdentifier("ownsNativeInstance");
public static readonly string CreateInstanceIdentifier = Generator.GeneratedIdentifier("CreateInstance");
public static readonly string GetOrCreateInstanceIdentifier = Generator.GeneratedIdentifier("GetOrCreateInstance");
public static string GetSuffixForInternal(DeclarationContext @class)
{

16
tests/CSharp/CSharp.Tests.cs

@ -767,6 +767,22 @@ public unsafe class CSharpTests @@ -767,6 +767,22 @@ public unsafe class CSharpTests
}
}
[Test]
public void TestEmbeddedArrayOfStructAccessor()
{
const ulong firstLong = 0xC92EEDE87AAB4FECul;
const ulong secondLong = 0xAD5FB16491935522ul;
var testStruct = new StructWithEmbeddedArrayOfStructObjectAlignment();
testStruct.EmbeddedStruct[0].Ui64 = firstLong;
testStruct.EmbeddedStruct[1].Ui64 = secondLong;
// Since the memory allocated for EmbeddedStruct is generally uninintialized, I suppose it _could_
// just happen to match, but it seems very unlikely.
Assert.That(firstLong, Is.EqualTo(testStruct.EmbeddedStruct[0].Ui64));
Assert.That(secondLong, Is.EqualTo(testStruct.EmbeddedStruct[1].Ui64));
}
public void TestClassSize()
{
Assert.That(Marshal.SizeOf<HasSecondaryBaseWithAbstractWithDefaultArg.__Internal>, Is.EqualTo(Marshal.SizeOf<IntPtr>() * 2));

2
tests/CSharp/CSharp.h

@ -1504,7 +1504,7 @@ struct DLL_API ClassMicrosoftObjectAlignment : ClassMicrosoftObjectAlignmentBase @@ -1504,7 +1504,7 @@ struct DLL_API ClassMicrosoftObjectAlignment : ClassMicrosoftObjectAlignmentBase
struct DLL_API EmbeddedStruct
{
int64_t i64;
uint64_t ui64;
};
struct DLL_API StructWithEmbeddedArrayOfStructObjectAlignment
{

Loading…
Cancel
Save