From de0392ca1ed56d5292c6af9c2c927d7dee64ebd4 Mon Sep 17 00:00:00 2001 From: Dimitar Dobrev Date: Sat, 27 Jun 2015 03:01:04 +0300 Subject: [PATCH] Fixed a bug when a function returns an abstract class contained in a dependency. Signed-off-by: Dimitar Dobrev --- .../Generators/CSharp/CSharpMarshal.cs | 15 +++-- .../Generators/CSharp/CSharpTextTemplate.cs | 62 +++++++++++-------- tests/NamespacesBase/NamespacesBase.h | 6 ++ tests/NamespacesDerived/NamespacesDerived.cpp | 5 ++ tests/NamespacesDerived/NamespacesDerived.h | 2 + 5 files changed, 55 insertions(+), 35 deletions(-) diff --git a/src/Generator/Generators/CSharp/CSharpMarshal.cs b/src/Generator/Generators/CSharp/CSharpMarshal.cs index 296b24ec..c7527eb6 100644 --- a/src/Generator/Generators/CSharp/CSharpMarshal.cs +++ b/src/Generator/Generators/CSharp/CSharpMarshal.cs @@ -264,12 +264,11 @@ namespace CppSharp.Generators.CSharp // if the class is an abstract impl, use the original for the object map var qualifiedClass = QualifiedIdentifier(originalClass); - var type = string.Format("{0}{1}", qualifiedClass, originalClass.IsAbstract ? "Internal" : ""); if (returnType.IsAddress()) - Context.Return.Write(HandleReturnedPointer(@class, type, qualifiedClass)); + Context.Return.Write(HandleReturnedPointer(@class, qualifiedClass)); else - Context.Return.Write("{0}.{1}({2})", type, Helpers.CreateInstanceIdentifier, Context.ReturnVarName); + Context.Return.Write("{0}.{1}({2})", qualifiedClass, Helpers.CreateInstanceIdentifier, Context.ReturnVarName); return true; } @@ -307,13 +306,13 @@ namespace CppSharp.Generators.CSharp return true; } - private string HandleReturnedPointer(Class @class, string type, string qualifiedClass) + private string HandleReturnedPointer(Class @class, string qualifiedClass) { var originalClass = @class.OriginalClass ?? @class; var ret = Generator.GeneratedIdentifier("result") + Context.ParameterIndex; Context.SupportBefore.WriteLine("{0} {1};", QualifiedIdentifier(@class), ret); Context.SupportBefore.WriteLine("if ({0} == IntPtr.Zero) {1} = {2};", Context.ReturnVarName, ret, - originalClass.IsRefType ? "null" : string.Format("new {0}()", type)); + originalClass.IsRefType ? "null" : string.Format("new {0}()", qualifiedClass)); if (originalClass.IsRefType) { Context.SupportBefore.WriteLine( @@ -324,18 +323,18 @@ namespace CppSharp.Generators.CSharp if (dtor != null && dtor.IsVirtual) { Context.SupportBefore.WriteLine("else {0}.NativeToManagedMap[{1}] = {2} = ({3}) {4}.{5}({1});", - qualifiedClass, Context.ReturnVarName, ret, QualifiedIdentifier(@class), type, + qualifiedClass, Context.ReturnVarName, ret, QualifiedIdentifier(@class), qualifiedClass, Helpers.CreateInstanceIdentifier, Context.ReturnVarName); } else { - Context.SupportBefore.WriteLine("else {0} = {1}.{2}({3});", ret, type, + Context.SupportBefore.WriteLine("else {0} = {1}.{2}({3});", ret, qualifiedClass, Helpers.CreateInstanceIdentifier, Context.ReturnVarName); } } else { - Context.SupportBefore.WriteLine("else {0} = {1}.{2}({3});", ret, type, + Context.SupportBefore.WriteLine("else {0} = {1}.{2}({3});", ret, qualifiedClass, Helpers.CreateInstanceIdentifier, Context.ReturnVarName); } return ret; diff --git a/src/Generator/Generators/CSharp/CSharpTextTemplate.cs b/src/Generator/Generators/CSharp/CSharpTextTemplate.cs index dd72864d..1047098c 100644 --- a/src/Generator/Generators/CSharp/CSharpTextTemplate.cs +++ b/src/Generator/Generators/CSharp/CSharpTextTemplate.cs @@ -1847,28 +1847,29 @@ namespace CppSharp.Generators.CSharp { PushBlock(CSharpBlockKind.Field); WriteLine("private readonly bool {0};", Helpers.OwnsNativeInstanceIdentifier); - PopBlock(NewLineKind.BeforeNextBlock); + PopBlock(NewLineKind.BeforeNextBlock); } string className = @class.IsAbstractImpl ? @class.BaseClass.Name : @class.Name; - if (!@class.IsAbstract) + var ctorCall = string.Format("{0}{1}", @class.Name, @class.IsAbstract ? "Internal" : ""); + if (!@class.IsAbstractImpl) { PushBlock(CSharpBlockKind.Method); WriteLine("public static {0}{1} {2}(global::System.IntPtr native)", @class.HasNonIgnoredBase && !@class.BaseClass.IsAbstract ? "new " : string.Empty, @class.Name, Helpers.CreateInstanceIdentifier); WriteStartBraceIndent(); - WriteLine("return new {0}(({1}.Internal*) native);", @class.Name, className); + WriteLine("return new {0}(({1}.Internal*) native);", ctorCall, className); WriteCloseBraceIndent(); PopBlock(NewLineKind.BeforeNextBlock); - - GenerateNativeConstructorByValue(@class, className, @class.Name); } + GenerateNativeConstructorByValue(@class, className, ctorCall); + PushBlock(CSharpBlockKind.Method); WriteLine("{0} {1}({2}.Internal* native, bool isInternalImpl = false){3}", - @class.IsRefType ? "protected" : "private", + @class.IsAbstractImpl ? "internal" : (@class.IsRefType ? "protected" : "private"), @class.Name, className, @class.IsValueType ? " : this()" : string.Empty); var hasBaseClass = @class.HasBaseClass && @class.BaseClass.IsRefType; @@ -1895,16 +1896,19 @@ namespace CppSharp.Generators.CSharp PopBlock(NewLineKind.BeforeNextBlock); } - private void GenerateNativeConstructorByValue(Class @class, string className, string safeIdentifier) + private void GenerateNativeConstructorByValue(Class @class, string className, string ctorCall) { - PushBlock(CSharpBlockKind.Method); - WriteLine("public static {0} {1}({0}.Internal native)", className, Helpers.CreateInstanceIdentifier); - WriteStartBraceIndent(); - WriteLine("return new {0}(native);", safeIdentifier); - WriteCloseBraceIndent(); - PopBlock(NewLineKind.BeforeNextBlock); + if (!@class.IsAbstractImpl) + { + PushBlock(CSharpBlockKind.Method); + WriteLine("public static {0} {1}({0}.Internal native)", className, Helpers.CreateInstanceIdentifier); + WriteStartBraceIndent(); + WriteLine("return new {0}(native);", ctorCall); + WriteCloseBraceIndent(); + PopBlock(NewLineKind.BeforeNextBlock); + } - if (@class.IsRefType) + if (@class.IsRefType && !@class.IsAbstract) { PushBlock(CSharpBlockKind.Method); WriteLine("private static {0}.Internal* __CopyValue({0}.Internal native)", className); @@ -1934,21 +1938,25 @@ namespace CppSharp.Generators.CSharp WriteCloseBraceIndent(); PopBlock(NewLineKind.BeforeNextBlock); } - PushBlock(CSharpBlockKind.Method); - WriteLine("private {0}({1}.Internal native)", safeIdentifier, className); - WriteLineIndent(@class.IsRefType ? ": this(__CopyValue(native))" : ": this()"); - WriteStartBraceIndent(); - if (@class.IsRefType) - { - WriteLine("{0} = true;", Helpers.OwnsNativeInstanceIdentifier); - WriteLine("NativeToManagedMap[{0}] = this;", Helpers.InstanceIdentifier); - } - else + if (!@class.IsAbstract) { - WriteLine("{0} = native;", Helpers.InstanceField); + PushBlock(CSharpBlockKind.Method); + WriteLine("{0} {1}({2}.Internal native)", + @class.IsAbstractImpl ? "internal" : "private", @class.Name, className); + WriteLineIndent(@class.IsRefType ? ": this(__CopyValue(native))" : ": this()"); + WriteStartBraceIndent(); + if (@class.IsRefType) + { + WriteLine("{0} = true;", Helpers.OwnsNativeInstanceIdentifier); + WriteLine("NativeToManagedMap[{0}] = this;", Helpers.InstanceIdentifier); + } + else + { + WriteLine("{0} = native;", Helpers.InstanceField); + } + WriteCloseBraceIndent(); + PopBlock(NewLineKind.BeforeNextBlock); } - WriteCloseBraceIndent(); - PopBlock(NewLineKind.BeforeNextBlock); } private void GenerateClassConstructorBase(Class @class, Method method) diff --git a/tests/NamespacesBase/NamespacesBase.h b/tests/NamespacesBase/NamespacesBase.h index 0caa7020..792a6d09 100644 --- a/tests/NamespacesBase/NamespacesBase.h +++ b/tests/NamespacesBase/NamespacesBase.h @@ -32,3 +32,9 @@ public: private: int b; }; + +class DLL_API Abstract +{ +public: + virtual void abstractFunction() = 0; +}; diff --git a/tests/NamespacesDerived/NamespacesDerived.cpp b/tests/NamespacesDerived/NamespacesDerived.cpp index 13a5c624..1d25a513 100644 --- a/tests/NamespacesDerived/NamespacesDerived.cpp +++ b/tests/NamespacesDerived/NamespacesDerived.cpp @@ -62,3 +62,8 @@ void Derived2::setNestedNSComponent(OverlappingNamespace::InDerivedLib c) void Derived2::defaultEnumValueFromDependency(OverlappingNamespace::ColorsEnum c) { } + +Abstract* Derived2::getAbstract() +{ + return 0; +} diff --git a/tests/NamespacesDerived/NamespacesDerived.h b/tests/NamespacesDerived/NamespacesDerived.h index 415f2fde..43458ae7 100644 --- a/tests/NamespacesDerived/NamespacesDerived.h +++ b/tests/NamespacesDerived/NamespacesDerived.h @@ -57,4 +57,6 @@ public: OverlappingNamespace::InDerivedLib getNestedNSComponent(); void setNestedNSComponent(OverlappingNamespace::InDerivedLib); void defaultEnumValueFromDependency(OverlappingNamespace::ColorsEnum c = OverlappingNamespace::ColorsEnum::black); + + Abstract* getAbstract(); };