Browse Source

Fixed the adjustment of the instance in cases of multiple inheritance.

Signed-off-by: Dimitar Dobrev <dpldobrev@protonmail.com>
pull/719/head
Dimitar Dobrev 9 years ago
parent
commit
e43dd1c18f
  1. 9
      src/Generator/Generators/CSharp/CSharpSources.cs
  2. 13
      src/Generator/Passes/MultipleInheritancePass.cs
  3. 2
      tests/CSharp/CSharp.Tests.cs
  4. 20
      tests/CSharp/CSharp.cpp
  5. 10
      tests/CSharp/CSharp.h

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

@ -2513,7 +2513,12 @@ namespace CppSharp.Generators.CSharp
private void GetVirtualCallDelegate(Method method, Class @class, private void GetVirtualCallDelegate(Method method, Class @class,
out string delegateId) out string delegateId)
{ {
var i = VTables.GetVTableIndex(method.OriginalFunction ?? method, @class); Function @virtual = method;
if (method.OriginalFunction != null &&
!((Class) method.OriginalFunction.Namespace).IsInterface)
@virtual = method.OriginalFunction;
var i = VTables.GetVTableIndex(@virtual, @class);
int vtableIndex = 0; int vtableIndex = 0;
if (Context.ParserOptions.IsMicrosoftAbi) if (Context.ParserOptions.IsMicrosoftAbi)
vtableIndex = @class.Layout.VFTables.IndexOf(@class.Layout.VFTables.Where( vtableIndex = @class.Layout.VFTables.IndexOf(@class.Layout.VFTables.Where(
@ -2526,7 +2531,7 @@ namespace CppSharp.Generators.CSharp
WriteStartBraceIndent(); WriteStartBraceIndent();
} }
var @delegate = GetVTableMethodDelegateName(method.OriginalFunction ?? method); var @delegate = GetVTableMethodDelegateName(@virtual);
delegateId = Generator.GeneratedIdentifier(@delegate); delegateId = Generator.GeneratedIdentifier(@delegate);
WriteLine("var {0} = ({1}) Marshal.GetDelegateForFunctionPointer(new IntPtr({2}), typeof({1}));", WriteLine("var {0} = ({1}) Marshal.GetDelegateForFunctionPointer(new IntPtr({2}), typeof({1}));",

13
src/Generator/Passes/MultipleInheritancePass.cs

@ -164,11 +164,16 @@ namespace CppSharp.Passes
{ {
foreach (var method in @interface.Methods) foreach (var method in @interface.Methods)
{ {
if (@class.Methods.Any(m => m.OriginalName == method.OriginalName && var existingImpl = @class.Methods.FirstOrDefault(
m.Parameters.Where(p => !p.Ignore).SequenceEqual( m => m.OriginalName == method.OriginalName &&
method.Parameters.Where(p => !p.Ignore), m.Parameters.Where(p => !p.Ignore).SequenceEqual(
ParameterTypeComparer.Instance))) method.Parameters.Where(p => !p.Ignore),
ParameterTypeComparer.Instance));
if (existingImpl != null)
{
existingImpl.OriginalFunction = method;
continue; continue;
}
var impl = new Method(method) var impl = new Method(method)
{ {
Namespace = @class, Namespace = @class,

2
tests/CSharp/CSharp.Tests.cs

@ -647,6 +647,8 @@ public unsafe class CSharpTests : GeneratorTestFixture
{ {
Assert.That(implementsAbstractsFromPrimaryAndSecondary.AbstractInPrimaryBase, Is.EqualTo(101)); Assert.That(implementsAbstractsFromPrimaryAndSecondary.AbstractInPrimaryBase, Is.EqualTo(101));
Assert.That(implementsAbstractsFromPrimaryAndSecondary.AbstractInSecondaryBase, Is.EqualTo(5)); Assert.That(implementsAbstractsFromPrimaryAndSecondary.AbstractInSecondaryBase, Is.EqualTo(5));
Assert.That(implementsAbstractsFromPrimaryAndSecondary.AbstractReturnsFieldInPrimaryBase, Is.EqualTo(201));
Assert.That(implementsAbstractsFromPrimaryAndSecondary.AbstractReturnsFieldInSecondaryBase, Is.EqualTo(202));
} }
} }

20
tests/CSharp/CSharp.cpp

@ -1222,7 +1222,15 @@ void HasMissingObjectOnVirtualCall::setMissingObjectOnVirtualCall(MissingObjectO
stackOverflowOnVirtualCall = value; stackOverflowOnVirtualCall = value;
} }
ImplementsAbstractsFromPrimaryAndSecondary::ImplementsAbstractsFromPrimaryAndSecondary() AbstractPrimaryBase::~AbstractPrimaryBase()
{
}
AbstractSecondaryBase::~AbstractSecondaryBase()
{
}
ImplementsAbstractsFromPrimaryAndSecondary::ImplementsAbstractsFromPrimaryAndSecondary() : field(200)
{ {
} }
@ -1239,3 +1247,13 @@ int ImplementsAbstractsFromPrimaryAndSecondary::abstractInSecondaryBase()
{ {
return 5; return 5;
} }
int ImplementsAbstractsFromPrimaryAndSecondary::abstractReturnsFieldInPrimaryBase()
{
return field + 1;
}
int ImplementsAbstractsFromPrimaryAndSecondary::abstractReturnsFieldInSecondaryBase()
{
return field + 2;
}

10
tests/CSharp/CSharp.h

@ -1095,20 +1095,28 @@ private:
class DLL_API AbstractPrimaryBase class DLL_API AbstractPrimaryBase
{ {
public: public:
virtual ~AbstractPrimaryBase();
virtual int abstractInPrimaryBase() = 0; virtual int abstractInPrimaryBase() = 0;
virtual int abstractReturnsFieldInPrimaryBase() = 0;
}; };
class DLL_API AbstractSecondaryBase class DLL_API AbstractSecondaryBase
{ {
public: public:
virtual ~AbstractSecondaryBase();
virtual int abstractInSecondaryBase() = 0; virtual int abstractInSecondaryBase() = 0;
virtual int abstractReturnsFieldInSecondaryBase() = 0;
}; };
class DLL_API ImplementsAbstractsFromPrimaryAndSecondary : public AbstractPrimaryBase, public AbstractSecondaryBase class DLL_API ImplementsAbstractsFromPrimaryAndSecondary : public AbstractPrimaryBase, public AbstractSecondaryBase
{ {
public: public:
ImplementsAbstractsFromPrimaryAndSecondary(); ImplementsAbstractsFromPrimaryAndSecondary();
~ImplementsAbstractsFromPrimaryAndSecondary(); virtual ~ImplementsAbstractsFromPrimaryAndSecondary();
virtual int abstractInPrimaryBase(); virtual int abstractInPrimaryBase();
virtual int abstractInSecondaryBase(); virtual int abstractInSecondaryBase();
virtual int abstractReturnsFieldInPrimaryBase();
virtual int abstractReturnsFieldInSecondaryBase();
private:
int field;
}; };

Loading…
Cancel
Save