Browse Source

Fixed a bug when a function returns an abstract class contained in a dependency.

Signed-off-by: Dimitar Dobrev <dpldobrev@yahoo.com>
pull/502/head
Dimitar Dobrev 10 years ago
parent
commit
de0392ca1e
  1. 15
      src/Generator/Generators/CSharp/CSharpMarshal.cs
  2. 62
      src/Generator/Generators/CSharp/CSharpTextTemplate.cs
  3. 6
      tests/NamespacesBase/NamespacesBase.h
  4. 5
      tests/NamespacesDerived/NamespacesDerived.cpp
  5. 2
      tests/NamespacesDerived/NamespacesDerived.h

15
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 // if the class is an abstract impl, use the original for the object map
var qualifiedClass = QualifiedIdentifier(originalClass); var qualifiedClass = QualifiedIdentifier(originalClass);
var type = string.Format("{0}{1}", qualifiedClass, originalClass.IsAbstract ? "Internal" : "");
if (returnType.IsAddress()) if (returnType.IsAddress())
Context.Return.Write(HandleReturnedPointer(@class, type, qualifiedClass)); Context.Return.Write(HandleReturnedPointer(@class, qualifiedClass));
else 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; return true;
} }
@ -307,13 +306,13 @@ namespace CppSharp.Generators.CSharp
return true; return true;
} }
private string HandleReturnedPointer(Class @class, string type, string qualifiedClass) private string HandleReturnedPointer(Class @class, string qualifiedClass)
{ {
var originalClass = @class.OriginalClass ?? @class; var originalClass = @class.OriginalClass ?? @class;
var ret = Generator.GeneratedIdentifier("result") + Context.ParameterIndex; var ret = Generator.GeneratedIdentifier("result") + Context.ParameterIndex;
Context.SupportBefore.WriteLine("{0} {1};", QualifiedIdentifier(@class), ret); Context.SupportBefore.WriteLine("{0} {1};", QualifiedIdentifier(@class), ret);
Context.SupportBefore.WriteLine("if ({0} == IntPtr.Zero) {1} = {2};", Context.ReturnVarName, 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) if (originalClass.IsRefType)
{ {
Context.SupportBefore.WriteLine( Context.SupportBefore.WriteLine(
@ -324,18 +323,18 @@ namespace CppSharp.Generators.CSharp
if (dtor != null && dtor.IsVirtual) if (dtor != null && dtor.IsVirtual)
{ {
Context.SupportBefore.WriteLine("else {0}.NativeToManagedMap[{1}] = {2} = ({3}) {4}.{5}({1});", 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); Helpers.CreateInstanceIdentifier, Context.ReturnVarName);
} }
else 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); Helpers.CreateInstanceIdentifier, Context.ReturnVarName);
} }
} }
else 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); Helpers.CreateInstanceIdentifier, Context.ReturnVarName);
} }
return ret; return ret;

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

@ -1847,28 +1847,29 @@ namespace CppSharp.Generators.CSharp
{ {
PushBlock(CSharpBlockKind.Field); PushBlock(CSharpBlockKind.Field);
WriteLine("private readonly bool {0};", Helpers.OwnsNativeInstanceIdentifier); WriteLine("private readonly bool {0};", Helpers.OwnsNativeInstanceIdentifier);
PopBlock(NewLineKind.BeforeNextBlock); PopBlock(NewLineKind.BeforeNextBlock);
} }
string className = @class.IsAbstractImpl ? @class.BaseClass.Name : @class.Name; 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); PushBlock(CSharpBlockKind.Method);
WriteLine("public static {0}{1} {2}(global::System.IntPtr native)", WriteLine("public static {0}{1} {2}(global::System.IntPtr native)",
@class.HasNonIgnoredBase && !@class.BaseClass.IsAbstract ? "new " : string.Empty, @class.HasNonIgnoredBase && !@class.BaseClass.IsAbstract ? "new " : string.Empty,
@class.Name, Helpers.CreateInstanceIdentifier); @class.Name, Helpers.CreateInstanceIdentifier);
WriteStartBraceIndent(); WriteStartBraceIndent();
WriteLine("return new {0}(({1}.Internal*) native);", @class.Name, className); WriteLine("return new {0}(({1}.Internal*) native);", ctorCall, className);
WriteCloseBraceIndent(); WriteCloseBraceIndent();
PopBlock(NewLineKind.BeforeNextBlock); PopBlock(NewLineKind.BeforeNextBlock);
GenerateNativeConstructorByValue(@class, className, @class.Name);
} }
GenerateNativeConstructorByValue(@class, className, ctorCall);
PushBlock(CSharpBlockKind.Method); PushBlock(CSharpBlockKind.Method);
WriteLine("{0} {1}({2}.Internal* native, bool isInternalImpl = false){3}", 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); @class.Name, className, @class.IsValueType ? " : this()" : string.Empty);
var hasBaseClass = @class.HasBaseClass && @class.BaseClass.IsRefType; var hasBaseClass = @class.HasBaseClass && @class.BaseClass.IsRefType;
@ -1895,16 +1896,19 @@ namespace CppSharp.Generators.CSharp
PopBlock(NewLineKind.BeforeNextBlock); PopBlock(NewLineKind.BeforeNextBlock);
} }
private void GenerateNativeConstructorByValue(Class @class, string className, string safeIdentifier) private void GenerateNativeConstructorByValue(Class @class, string className, string ctorCall)
{ {
PushBlock(CSharpBlockKind.Method); if (!@class.IsAbstractImpl)
WriteLine("public static {0} {1}({0}.Internal native)", className, Helpers.CreateInstanceIdentifier); {
WriteStartBraceIndent(); PushBlock(CSharpBlockKind.Method);
WriteLine("return new {0}(native);", safeIdentifier); WriteLine("public static {0} {1}({0}.Internal native)", className, Helpers.CreateInstanceIdentifier);
WriteCloseBraceIndent(); WriteStartBraceIndent();
PopBlock(NewLineKind.BeforeNextBlock); WriteLine("return new {0}(native);", ctorCall);
WriteCloseBraceIndent();
PopBlock(NewLineKind.BeforeNextBlock);
}
if (@class.IsRefType) if (@class.IsRefType && !@class.IsAbstract)
{ {
PushBlock(CSharpBlockKind.Method); PushBlock(CSharpBlockKind.Method);
WriteLine("private static {0}.Internal* __CopyValue({0}.Internal native)", className); WriteLine("private static {0}.Internal* __CopyValue({0}.Internal native)", className);
@ -1934,21 +1938,25 @@ namespace CppSharp.Generators.CSharp
WriteCloseBraceIndent(); WriteCloseBraceIndent();
PopBlock(NewLineKind.BeforeNextBlock); PopBlock(NewLineKind.BeforeNextBlock);
} }
PushBlock(CSharpBlockKind.Method); if (!@class.IsAbstract)
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
{ {
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) private void GenerateClassConstructorBase(Class @class, Method method)

6
tests/NamespacesBase/NamespacesBase.h

@ -32,3 +32,9 @@ public:
private: private:
int b; int b;
}; };
class DLL_API Abstract
{
public:
virtual void abstractFunction() = 0;
};

5
tests/NamespacesDerived/NamespacesDerived.cpp

@ -62,3 +62,8 @@ void Derived2::setNestedNSComponent(OverlappingNamespace::InDerivedLib c)
void Derived2::defaultEnumValueFromDependency(OverlappingNamespace::ColorsEnum c) void Derived2::defaultEnumValueFromDependency(OverlappingNamespace::ColorsEnum c)
{ {
} }
Abstract* Derived2::getAbstract()
{
return 0;
}

2
tests/NamespacesDerived/NamespacesDerived.h

@ -57,4 +57,6 @@ public:
OverlappingNamespace::InDerivedLib getNestedNSComponent(); OverlappingNamespace::InDerivedLib getNestedNSComponent();
void setNestedNSComponent(OverlappingNamespace::InDerivedLib); void setNestedNSComponent(OverlappingNamespace::InDerivedLib);
void defaultEnumValueFromDependency(OverlappingNamespace::ColorsEnum c = OverlappingNamespace::ColorsEnum::black); void defaultEnumValueFromDependency(OverlappingNamespace::ColorsEnum c = OverlappingNamespace::ColorsEnum::black);
Abstract* getAbstract();
}; };

Loading…
Cancel
Save