diff --git a/src/Generator/Generators/CSharp/CSharpSources.cs b/src/Generator/Generators/CSharp/CSharpSources.cs index 9473d10f..40d462ca 100644 --- a/src/Generator/Generators/CSharp/CSharpSources.cs +++ b/src/Generator/Generators/CSharp/CSharpSources.cs @@ -2515,8 +2515,12 @@ namespace CppSharp.Generators.CSharp out string delegateId) { var i = VTables.GetVTableIndex(method.OriginalFunction ?? method, @class); - WriteLine("var {0} = *(void**) ((IntPtr) __OriginalVTables[0] + {1} * {2});", - Helpers.SlotIdentifier, i, Context.TargetInfo.PointerWidth / 8); + int vtableIndex = 0; + if (Context.ParserOptions.IsMicrosoftAbi) + vtableIndex = @class.Layout.VFTables.IndexOf(@class.Layout.VFTables.Where( + v => v.Layout.Components.Any(c => c.Method.OriginalPtr == method.OriginalPtr)).First()); + WriteLine("var {0} = *(void**) ((IntPtr) __OriginalVTables[{1}] + {2} * {3});", + Helpers.SlotIdentifier, vtableIndex, i, Context.TargetInfo.PointerWidth / 8); if (method.IsDestructor && @class.IsAbstract) { WriteLine("if ({0} != null)", Helpers.SlotIdentifier); diff --git a/tests/CSharp/CSharp.Tests.cs b/tests/CSharp/CSharp.Tests.cs index 7de9c57d..86939716 100644 --- a/tests/CSharp/CSharp.Tests.cs +++ b/tests/CSharp/CSharp.Tests.cs @@ -627,6 +627,29 @@ public unsafe class CSharpTests : GeneratorTestFixture } } + [Test] + public void TestStackOverflowOnVirtualCall() + { + using (var hasMissingObjectOnVirtualCall = new HasMissingObjectOnVirtualCall()) + { + using (var missingObjectOnVirtualCall = new MissingObjectOnVirtualCall()) + { + hasMissingObjectOnVirtualCall.SetMissingObjectOnVirtualCall(missingObjectOnVirtualCall); + hasMissingObjectOnVirtualCall.MakeMissingObjectOnVirtualCall(); + } + } + } + + [Test] + public void TestAbstractImplementatonsInPrimaryAndSecondaryBases() + { + using (var implementsAbstractsFromPrimaryAndSecondary = new ImplementsAbstractsFromPrimaryAndSecondary()) + { + Assert.That(implementsAbstractsFromPrimaryAndSecondary.AbstractInPrimaryBase, Is.EqualTo(101)); + Assert.That(implementsAbstractsFromPrimaryAndSecondary.AbstractInSecondaryBase, Is.EqualTo(5)); + } + } + private class OverrideVirtualWithString : HasVirtualTakesReturnsProblematicTypes { public override string VirtualTakesAndReturnsString(string c) @@ -647,17 +670,4 @@ public unsafe class CSharpTests : GeneratorTestFixture return base.HasPointerToEnumInParam(pointerToEnum); } } - - [Test] - public void TestStackOverflowOnVirtualCall() - { - using (var hasMissingObjectOnVirtualCall = new HasMissingObjectOnVirtualCall()) - { - using (var missingObjectOnVirtualCall = new MissingObjectOnVirtualCall()) - { - hasMissingObjectOnVirtualCall.SetMissingObjectOnVirtualCall(missingObjectOnVirtualCall); - hasMissingObjectOnVirtualCall.MakeMissingObjectOnVirtualCall(); - } - } - } -} +} \ No newline at end of file diff --git a/tests/CSharp/CSharp.cpp b/tests/CSharp/CSharp.cpp index ddb12581..ada200e4 100644 --- a/tests/CSharp/CSharp.cpp +++ b/tests/CSharp/CSharp.cpp @@ -1221,3 +1221,21 @@ void HasMissingObjectOnVirtualCall::setMissingObjectOnVirtualCall(MissingObjectO { stackOverflowOnVirtualCall = value; } + +ImplementsAbstractsFromPrimaryAndSecondary::ImplementsAbstractsFromPrimaryAndSecondary() +{ +} + +ImplementsAbstractsFromPrimaryAndSecondary::~ImplementsAbstractsFromPrimaryAndSecondary() +{ +} + +int ImplementsAbstractsFromPrimaryAndSecondary::abstractInPrimaryBase() +{ + return 101; +} + +int ImplementsAbstractsFromPrimaryAndSecondary::abstractInSecondaryBase() +{ + return 5; +} diff --git a/tests/CSharp/CSharp.h b/tests/CSharp/CSharp.h index ffe86843..910fd8f4 100644 --- a/tests/CSharp/CSharp.h +++ b/tests/CSharp/CSharp.h @@ -1091,3 +1091,24 @@ public: private: MissingObjectOnVirtualCall* stackOverflowOnVirtualCall; }; + +class DLL_API AbstractPrimaryBase +{ +public: + virtual int abstractInPrimaryBase() = 0; +}; + +class DLL_API AbstractSecondaryBase +{ +public: + virtual int abstractInSecondaryBase() = 0; +}; + +class DLL_API ImplementsAbstractsFromPrimaryAndSecondary : public AbstractPrimaryBase, public AbstractSecondaryBase +{ +public: + ImplementsAbstractsFromPrimaryAndSecondary(); + ~ImplementsAbstractsFromPrimaryAndSecondary(); + virtual int abstractInPrimaryBase(); + virtual int abstractInSecondaryBase(); +};