diff --git a/src/AST/FunctionExtensions.cs b/src/AST/FunctionExtensions.cs index 36ba64b4..c437fcfe 100644 --- a/src/AST/FunctionExtensions.cs +++ b/src/AST/FunctionExtensions.cs @@ -33,7 +33,9 @@ namespace CppSharp.AST { @params.Add(new Parameter { - QualifiedType = universalDelegate && param.Kind == ParameterKind.IndirectReturnType ? + QualifiedType = universalDelegate && + (param.Kind == ParameterKind.IndirectReturnType || + param.Type.Desugar().IsPointerTo(out FunctionType functionType)) ? pointer : param.QualifiedType, Kind = param.Kind, Usage = param.Usage, diff --git a/src/Generator/Generators/CSharp/CSharpSources.cs b/src/Generator/Generators/CSharp/CSharpSources.cs index 062ec222..bb2d7258 100644 --- a/src/Generator/Generators/CSharp/CSharpSources.cs +++ b/src/Generator/Generators/CSharp/CSharpSources.cs @@ -1835,7 +1835,7 @@ namespace CppSharp.Generators.CSharp } TypePrinterResult retType; - TypePrinter.PushMarshalKind(MarshalKind.GenericDelegate); + TypePrinter.PushMarshalKind(MarshalKind.VTableReturnValue); var @params = GatherInternalParams(method, out retType); var vTableMethodDelegateName = GetVTableMethodDelegateName(method); diff --git a/src/Generator/Passes/DelegatesPass.cs b/src/Generator/Passes/DelegatesPass.cs index bc03c995..6ff81123 100644 --- a/src/Generator/Passes/DelegatesPass.cs +++ b/src/Generator/Passes/DelegatesPass.cs @@ -73,11 +73,13 @@ namespace CppSharp.Passes ReturnType = method.ReturnType }; + TypePrinter.PushMarshalKind(MarshalKind.VTableReturnValue); functionType.Parameters.AddRange( method.GatherInternalParams(Context.ParserOptions.IsItaniumLikeAbi, true)); method.FunctionType = CheckForDelegate(new QualifiedType(functionType), method.Namespace, @private: true); + TypePrinter.PopMarshalKind(); return true; } diff --git a/tests/Common/Common.Tests.cs b/tests/Common/Common.Tests.cs index b5dee8f7..bed5ae59 100644 --- a/tests/Common/Common.Tests.cs +++ b/tests/Common/Common.Tests.cs @@ -576,6 +576,9 @@ public class CommonTests : GeneratorTestFixture Assert.That(prop.conflict, Is.EqualTo(CommonTest.TestProperties.Conflict.Value1)); prop.conflict = CommonTest.TestProperties.Conflict.Value2; Assert.That(prop.conflict, Is.EqualTo(CommonTest.TestProperties.Conflict.Value2)); + + prop.Callback = x => 4 * x; + Assert.That(prop.Callback(5), Is.EqualTo(20)); } using (var prop = new HasOverridenSetter()) { diff --git a/tests/Common/Common.cpp b/tests/Common/Common.cpp index d3ceba4b..89329b7e 100644 --- a/tests/Common/Common.cpp +++ b/tests/Common/Common.cpp @@ -718,6 +718,16 @@ void TestProperties::SetConflict(Conflict conflict) _conflict = conflict; } +int(*TestProperties::getCallback())(int) +{ + return _callback; +} + +void TestProperties::setCallback(int(*value)(int)) +{ + _callback = value; +} + HasOverridenSetter::HasOverridenSetter() { } diff --git a/tests/Common/Common.h b/tests/Common/Common.h index b0422a6c..5192e2de 100644 --- a/tests/Common/Common.h +++ b/tests/Common/Common.h @@ -649,6 +649,9 @@ public: Conflict GetConflict(); void SetConflict(Conflict _conflict); + virtual int(*getCallback())(int); + virtual void setCallback(int(*value)(int)); + private: int FieldValue; double _refToPrimitiveInSetter; @@ -656,6 +659,7 @@ private: int _setterReturnsBoolean; int _virtualSetterReturnsBoolean; Conflict _conflict; + int(*_callback)(int); }; class DLL_API HasOverridenSetter : public TestProperties