Browse Source

Corrected the implementation of abstract methods to properly handle classes, instance arguments and indirect return types.

Signed-off-by: Dimitar Dobrev <dpldobrev@yahoo.com>
pull/53/head
Dimitar Dobrev 13 years ago
parent
commit
4cfcfa1b16
  1. 15
      src/Generator/Generators/CSharp/CSharpTextTemplate.cs
  2. 28
      src/Generator/Passes/AbstractImplementationsPass.cs
  3. 2
      tests/Basic/Basic.Tests.cs

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

@ -1528,7 +1528,7 @@ namespace CppSharp.Generators.CSharp @@ -1528,7 +1528,7 @@ namespace CppSharp.Generators.CSharp
}
else if (method.IsOverride && method.IsSynthetized)
{
GenerateVirtualTableMethodCall(method, @class);
GenerateVirtualTableFunctionCall(method, @class);
}
else
{
@ -1557,7 +1557,7 @@ namespace CppSharp.Generators.CSharp @@ -1557,7 +1557,7 @@ namespace CppSharp.Generators.CSharp
PopBlock(NewLineKind.BeforeNextBlock);
}
private void GenerateVirtualTableMethodCall(Method method, Class @class)
private void GenerateVirtualTableFunctionCall(Method method, Class @class)
{
WriteLine("void* vtable = *((void**) __Instance.ToPointer());");
int i;
@ -1573,15 +1573,12 @@ namespace CppSharp.Generators.CSharp @@ -1573,15 +1573,12 @@ namespace CppSharp.Generators.CSharp
i = @class.Layout.Layout.Components.FindIndex(m => m.Method == method);
break;
}
WriteLine("void* slot = *((void**) vtable + {0} * sizeof(IntPtr));", i);
WriteLine("void* slot = *((void**) vtable + {0} * IntPtr.Size);", i);
string @delegate = method.Name + "Delegate";
string delegateId = GeneratedIdentifier(@delegate);
WriteLine("{0} {1} = ({0}) Marshal.GetDelegateForFunctionPointer(new IntPtr(slot), typeof({0}));",
WriteLine("var {1} = ({0}) Marshal.GetDelegateForFunctionPointer(new IntPtr(slot), typeof({0}));",
@delegate, delegateId);
if (!method.OriginalReturnType.Type.IsPrimitiveType(PrimitiveType.Void))
Write("return ");
WriteLine("{0}({1});", delegateId, string.Join(", ", method.Parameters.Where(
p => p.Kind != ParameterKind.IndirectReturnType).Select(p => Helpers.SafeIdentifier(p.Name))));
GenerateFunctionCall(delegateId, method.Parameters, method);
}
private void GenerateOperator(Method method, Class @class)
@ -1937,9 +1934,11 @@ namespace CppSharp.Generators.CSharp @@ -1937,9 +1934,11 @@ namespace CppSharp.Generators.CSharp
PushBlock(CSharpBlockKind.Typedef);
WriteLine("[UnmanagedFunctionPointerAttribute(CallingConvention.{0})]",
Helpers.ToCSharpCallConv(functionType.CallingConvention));
TypePrinter.PushContext(CSharpTypePrinterContextKind.Native);
WriteLine("public {0};",
string.Format(TypePrinter.VisitDelegate(functionType).Type,
SafeIdentifier(typedef.Name)));
TypePrinter.PopContext();
PopBlock(NewLineKind.BeforeNextBlock);
}
else if (typedef.Type.IsEnumType())

28
src/Generator/Passes/AbstractImplementationsPass.cs

@ -1,5 +1,4 @@ @@ -1,5 +1,4 @@
using System;
using System.Collections.Generic;
using System.Collections.Generic;
using System.Linq;
using CppSharp.AST;
using CppSharp.Utils;
@ -57,12 +56,29 @@ namespace CppSharp.Passes @@ -57,12 +56,29 @@ namespace CppSharp.Passes
{
internalImplementation.Methods.Add(new Method(abstractMethod));
var @delegate = new TypedefDecl { Name = abstractMethod.Name + "Delegate" };
var pointerType = new PointerType();
var functionType = new FunctionType();
functionType.CallingConvention = abstractMethod.CallingConvention;
functionType.ReturnType = abstractMethod.OriginalReturnType;
functionType.Parameters.AddRange(abstractMethod.Parameters.Where(
p => p.Kind != ParameterKind.IndirectReturnType));
functionType.ReturnType = abstractMethod.ReturnType;
var instance = new Parameter();
instance.Name = "instance";
instance.QualifiedType = new QualifiedType(new BuiltinType(PrimitiveType.IntPtr));
functionType.Parameters.Add(instance);
functionType.Parameters.AddRange(abstractMethod.Parameters);
for (int i = functionType.Parameters.Count - 1; i >= 0; i--)
{
var parameter = functionType.Parameters[i];
if (parameter.Kind == ParameterKind.IndirectReturnType)
{
var retParam = new Parameter();
retParam.Name = parameter.Name;
var ptrType = new PointerType();
ptrType.QualifiedPointee = new QualifiedType(parameter.Type);
retParam.QualifiedType = new QualifiedType(ptrType);
functionType.Parameters.RemoveAt(i);
functionType.Parameters.Insert(i, retParam);
}
}
var pointerType = new PointerType();
pointerType.QualifiedPointee = new QualifiedType(functionType);
@delegate.QualifiedType = new QualifiedType(pointerType);
@delegate.IgnoreFlags = abstractMethod.IgnoreFlags;

2
tests/Basic/Basic.Tests.cs

@ -90,7 +90,7 @@ public class BasicTests @@ -90,7 +90,7 @@ public class BasicTests
public void TestAbstractReturnType()
{
var returnsAbstractFoo = new ReturnsAbstractFoo();
AbstractFoo abstractFoo = returnsAbstractFoo.getFoo();
var abstractFoo = returnsAbstractFoo.getFoo();
Assert.AreEqual(abstractFoo.pureFunction(), 5);
}
}

Loading…
Cancel
Save