Browse Source

Fixed the offsets of fields when using multiple inheritance.

Signed-off-by: Dimitar Dobrev <dpldobrev@yahoo.com>
pull/564/merge
Dimitar Dobrev 10 years ago
parent
commit
0950b869a1
  1. 19
      src/Generator/Generators/CSharp/CSharpTextTemplate.cs
  2. 15
      tests/CSharp/CSharp.Tests.cs
  3. 12
      tests/CSharp/CSharp.cpp
  4. 22
      tests/CSharp/CSharp.h

19
src/Generator/Generators/CSharp/CSharpTextTemplate.cs

@ -515,7 +515,7 @@ namespace CppSharp.Generators.CSharp
TypePrinter.PushContext(CSharpTypePrinterContextKind.Native); TypePrinter.PushContext(CSharpTypePrinterContextKind.Native);
GenerateClassFields(@class, GenerateClassInternalsField, true); GenerateClassFields(@class, @class, GenerateClassInternalsField, true);
if (@class.IsGenerated) if (@class.IsGenerated)
{ {
if (@class.IsDynamic) if (@class.IsDynamic)
@ -709,7 +709,8 @@ namespace CppSharp.Generators.CSharp
Write(" : {0}", string.Join(", ", bases)); Write(" : {0}", string.Join(", ", bases));
} }
public void GenerateClassFields(Class @class, Action<Field> action, bool nativeFields = false) public void GenerateClassFields(Class owner, Class @class,
Action<Class, Field> action, bool nativeFields = false)
{ {
foreach (var @base in @class.Bases.Where(b => b.Class != null)) foreach (var @base in @class.Bases.Where(b => b.Class != null))
{ {
@ -718,17 +719,17 @@ namespace CppSharp.Generators.CSharp
@base.Class.OriginalClass == @class) @base.Class.OriginalClass == @class)
continue; continue;
GenerateClassFields(@base.Class, action, nativeFields); GenerateClassFields(owner, @base.Class, action, nativeFields);
} }
foreach (var field in @class.Fields) foreach (var field in @class.Fields)
{ {
if (ASTUtils.CheckIgnoreField(field, nativeFields)) continue; if (ASTUtils.CheckIgnoreField(field, nativeFields)) continue;
action(field); action(owner, field);
} }
} }
private void GenerateClassInternalsField(Field field) private void GenerateClassInternalsField(Class owner, Field field)
{ {
// we do not support dependent fields yet, see https://github.com/mono/CppSharp/issues/197 // we do not support dependent fields yet, see https://github.com/mono/CppSharp/issues/197
Class @class; Class @class;
@ -746,7 +747,8 @@ namespace CppSharp.Generators.CSharp
PushBlock(CSharpBlockKind.Field); PushBlock(CSharpBlockKind.Field);
WriteLine("[FieldOffset({0})]", field.OffsetInBytes); WriteLine("[FieldOffset({0})]", field.OffsetInBytes +
owner.ComputeNonVirtualBaseClassOffsetTo((Class) field.Namespace));
TypePrinter.PushMarshalKind(CSharpMarshalKind.NativeField); TypePrinter.PushMarshalKind(CSharpMarshalKind.NativeField);
var fieldTypePrinted = field.QualifiedType.CSharpType(TypePrinter); var fieldTypePrinted = field.QualifiedType.CSharpType(TypePrinter);
@ -782,10 +784,11 @@ namespace CppSharp.Generators.CSharp
Name = string.Format("{0}_{1}_{2}", Helpers.DummyIdentifier, Name = string.Format("{0}_{1}_{2}", Helpers.DummyIdentifier,
safeIdentifier, i), safeIdentifier, i),
QualifiedType = new QualifiedType(arrayType.Type), QualifiedType = new QualifiedType(arrayType.Type),
Offset = (uint)(field.Offset + (i * arrayType.ElementSize)) Offset = (uint) (field.Offset + i * arrayType.ElementSize),
Namespace = owner
}; };
GenerateClassInternalsField(dummy); GenerateClassInternalsField(owner, dummy);
} }
} }
} }

15
tests/CSharp/CSharp.Tests.cs

@ -479,7 +479,20 @@ public class CSharpTests : GeneratorTestFixture
{ {
using (new QApplication()) using (new QApplication())
{ {
new QWidget(); using (new QWidget())
{
}
}
}
[Test]
public void TestMultipleInheritanceFieldOffsets()
{
using (var multipleInheritanceFieldOffsets = new MultipleInheritanceFieldOffsets())
{
Assert.That(multipleInheritanceFieldOffsets.Primary, Is.EqualTo(1));
Assert.That(multipleInheritanceFieldOffsets.Secondary, Is.EqualTo(2));
Assert.That(multipleInheritanceFieldOffsets.Own, Is.EqualTo(3));
} }
} }
} }

12
tests/CSharp/CSharp.cpp

@ -894,3 +894,15 @@ char* HasSamePropertyInDerivedAbstractType::property()
InheritsFromHasSamePropertyInDerivedAbstractType::InheritsFromHasSamePropertyInDerivedAbstractType() InheritsFromHasSamePropertyInDerivedAbstractType::InheritsFromHasSamePropertyInDerivedAbstractType()
{ {
} }
MultipleInheritanceFieldOffsetsSecondaryBase::MultipleInheritanceFieldOffsetsSecondaryBase() : secondary(2)
{
}
MultipleInheritanceFieldOffsetsPrimaryBase::MultipleInheritanceFieldOffsetsPrimaryBase() : primary(1)
{
}
MultipleInheritanceFieldOffsets::MultipleInheritanceFieldOffsets() : own(3)
{
}

22
tests/CSharp/CSharp.h

@ -806,3 +806,25 @@ public:
InheritsFromHasSamePropertyInDerivedAbstractType(); InheritsFromHasSamePropertyInDerivedAbstractType();
virtual int property() = 0; virtual int property() = 0;
}; };
class DLL_API MultipleInheritanceFieldOffsetsSecondaryBase
{
public:
MultipleInheritanceFieldOffsetsSecondaryBase();
int secondary;
};
class DLL_API MultipleInheritanceFieldOffsetsPrimaryBase
{
public:
MultipleInheritanceFieldOffsetsPrimaryBase();
int primary;
};
class DLL_API MultipleInheritanceFieldOffsets : public MultipleInheritanceFieldOffsetsPrimaryBase, public MultipleInheritanceFieldOffsetsSecondaryBase
{
public:
MultipleInheritanceFieldOffsets();
int own;
};

Loading…
Cancel
Save