Browse Source

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

Fixes https://github.com/mono/CppSharp/issues/707.

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

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

@ -2513,7 +2513,12 @@ namespace CppSharp.Generators.CSharp @@ -2513,7 +2513,12 @@ namespace CppSharp.Generators.CSharp
private void GetVirtualCallDelegate(Method method, Class @class,
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;
if (Context.ParserOptions.IsMicrosoftAbi)
vtableIndex = @class.Layout.VFTables.IndexOf(@class.Layout.VFTables.Where(
@ -2526,7 +2531,7 @@ namespace CppSharp.Generators.CSharp @@ -2526,7 +2531,7 @@ namespace CppSharp.Generators.CSharp
WriteStartBraceIndent();
}
var @delegate = GetVTableMethodDelegateName(method.OriginalFunction ?? method);
var @delegate = GetVTableMethodDelegateName(@virtual);
delegateId = Generator.GeneratedIdentifier(@delegate);
WriteLine("var {0} = ({1}) Marshal.GetDelegateForFunctionPointer(new IntPtr({2}), typeof({1}));",
@ -2823,11 +2828,14 @@ namespace CppSharp.Generators.CSharp @@ -2823,11 +2828,14 @@ namespace CppSharp.Generators.CSharp
WriteCloseBraceIndent();
}
private static string GetInstanceParam(Function function)
private string GetInstanceParam(Function function)
{
var from = (Class) function.Namespace;
var to = function.OriginalFunction == null ? @from.BaseClass :
(Class) function.OriginalFunction.Namespace;
var to = function.OriginalFunction == null ||
// we don't need to offset the instance with Itanium if there's an existing interface impl
(Context.ParserOptions.IsItaniumLikeAbi &&
!((Class) function.OriginalNamespace).IsInterface) ?
@from.BaseClass : (Class) function.OriginalFunction.Namespace;
var baseOffset = 0u;
if (to != null)

11
src/Generator/Passes/MultipleInheritancePass.cs

@ -160,15 +160,20 @@ namespace CppSharp.Passes @@ -160,15 +160,20 @@ namespace CppSharp.Passes
return interfaceProperty;
}
private static void ImplementInterfaceMethods(Class @class, Class @interface)
private void ImplementInterfaceMethods(Class @class, Class @interface)
{
foreach (var method in @interface.Methods)
{
if (@class.Methods.Any(m => m.OriginalName == method.OriginalName &&
var existingImpl = @class.Methods.FirstOrDefault(
m => m.OriginalName == method.OriginalName &&
m.Parameters.Where(p => !p.Ignore).SequenceEqual(
method.Parameters.Where(p => !p.Ignore),
ParameterTypeComparer.Instance)))
ParameterTypeComparer.Instance));
if (existingImpl != null)
{
existingImpl.OriginalFunction = method;
continue;
}
var impl = new Method(method)
{
Namespace = @class,

2
tests/CSharp/CSharp.Tests.cs

@ -647,6 +647,8 @@ public unsafe class CSharpTests : GeneratorTestFixture @@ -647,6 +647,8 @@ public unsafe class CSharpTests : GeneratorTestFixture
{
Assert.That(implementsAbstractsFromPrimaryAndSecondary.AbstractInPrimaryBase, Is.EqualTo(101));
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 @@ -1222,7 +1222,15 @@ void HasMissingObjectOnVirtualCall::setMissingObjectOnVirtualCall(MissingObjectO
stackOverflowOnVirtualCall = value;
}
ImplementsAbstractsFromPrimaryAndSecondary::ImplementsAbstractsFromPrimaryAndSecondary()
AbstractPrimaryBase::~AbstractPrimaryBase()
{
}
AbstractSecondaryBase::~AbstractSecondaryBase()
{
}
ImplementsAbstractsFromPrimaryAndSecondary::ImplementsAbstractsFromPrimaryAndSecondary() : field(200)
{
}
@ -1239,3 +1247,13 @@ int ImplementsAbstractsFromPrimaryAndSecondary::abstractInSecondaryBase() @@ -1239,3 +1247,13 @@ int ImplementsAbstractsFromPrimaryAndSecondary::abstractInSecondaryBase()
{
return 5;
}
int ImplementsAbstractsFromPrimaryAndSecondary::abstractReturnsFieldInPrimaryBase()
{
return field + 1;
}
int ImplementsAbstractsFromPrimaryAndSecondary::abstractReturnsFieldInSecondaryBase()
{
return field + 2;
}

10
tests/CSharp/CSharp.h

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

Loading…
Cancel
Save