diff --git a/src/Generator/Generators/CSharp/CSharpMarshal.cs b/src/Generator/Generators/CSharp/CSharpMarshal.cs index db560b61..48049cc6 100644 --- a/src/Generator/Generators/CSharp/CSharpMarshal.cs +++ b/src/Generator/Generators/CSharp/CSharpMarshal.cs @@ -250,10 +250,12 @@ namespace CppSharp.Generators.CSharp { var ctx = Context as CSharpMarshalContext; - string instance = Context.ReturnVarName; + var instance = Context.ReturnVarName; + @class = @class.OriginalClass ?? @class; + Type returnType = Context.ReturnType.Type.Desugar(); if (@class.IsRefType && - (Context.ReturnType.Qualifiers.IsConst || !Context.ReturnType.Type.IsAddress()) && + (Context.ReturnType.Qualifiers.IsConst || !returnType.IsAddress()) && (!Context.Driver.Options.GenerateAbstractImpls || !@class.IsAbstract)) { var instanceName = Generator.GeneratedIdentifier("instance"); @@ -299,16 +301,16 @@ namespace CppSharp.Generators.CSharp instance = instanceName; } + + var type = QualifiedIdentifier(@class) + + (Context.Driver.Options.GenerateAbstractImpls && @class.IsAbstract ? + "Internal" : ""); - if (@class.IsRefType) - Context.Return.Write("({0} == IntPtr.Zero) ? null : ", - instance); + if (returnType.IsAddress()) + Context.Return.Write("({0} == IntPtr.Zero) ? {1} : ", instance, + @class.IsRefType ? "null" : string.Format("new {0}()", type)); - Context.Return.Write("new {0}({1})", - QualifiedIdentifier(@class.OriginalClass ?? @class) + - (Context.Driver.Options.GenerateAbstractImpls && @class.IsAbstract ? - "Internal" : ""), - instance); + Context.Return.Write("new {0}({1})", type, instance); return true; } diff --git a/tests/TypeMaps/QList.cs b/tests/TypeMaps/QList.cs new file mode 100644 index 00000000..2b6e5f0f --- /dev/null +++ b/tests/TypeMaps/QList.cs @@ -0,0 +1,57 @@ +using CppSharp.AST.Extensions; +using CppSharp.Generators; +using CppSharp.Generators.CLI; +using CppSharp.Generators.CSharp; +using CppSharp.Types; + +namespace TypeMaps.Gen +{ + [TypeMap("QList")] + public class QList : TypeMap + { + public override bool DoesMarshalling + { + get { return false; } + } + + public override string CLISignature(CLITypePrinterContext ctx) + { + return "TypeMaps::QList^"; + } + + public override void CLIMarshalToManaged(MarshalContext ctx) + { + } + + public override void CLIMarshalToNative(MarshalContext ctx) + { + } + + public override string CSharpSignature(CSharpTypePrinterContext ctx) + { + if (ctx.CSharpKind == CSharpTypePrinterContextKind.Native) + { + if (Type.IsAddress()) + { + return "QList.Internal*"; + } + return "QList.Internal"; + } + return "QList"; + } + + public override void CSharpMarshalToManaged(MarshalContext ctx) + { + } + + public override void CSharpMarshalToNative(MarshalContext ctx) + { + } + + public override void CSharpMarshalCopyCtorToManaged(MarshalContext ctx) + { + ctx.SupportBefore.WriteLine("var __instance = new {0}.Internal();", ctx.ReturnType); + ctx.SupportBefore.WriteLine("__instance.i = {0}.i;", ctx.ReturnVarName); + } + } +} diff --git a/tests/TypeMaps/TypeMaps.cpp b/tests/TypeMaps/TypeMaps.cpp new file mode 100644 index 00000000..154afc88 --- /dev/null +++ b/tests/TypeMaps/TypeMaps.cpp @@ -0,0 +1,11 @@ +#include "TypeMaps.h" +#include + +QList::QList() : i(5) +{ +} + +QList HasQList::getList() +{ + return list; +} diff --git a/tests/TypeMaps/TypeMaps.cs b/tests/TypeMaps/TypeMaps.cs new file mode 100644 index 00000000..91d041fe --- /dev/null +++ b/tests/TypeMaps/TypeMaps.cs @@ -0,0 +1,40 @@ +using System.Linq; +using CppSharp.AST; +using CppSharp.Generators; +using CppSharp.Utils; + +namespace CppSharp.Tests +{ + public class TypeMaps : GeneratorTest + { + public TypeMaps(GeneratorKind kind) + : base("TypeMaps", kind) + { + + } + + public override void SetupPasses(Driver driver) + { + if (driver.Options.IsCSharpGenerator) + driver.Options.GenerateAbstractImpls = true; + driver.Options.GenerateVirtualTables = true; + driver.Options.GenerateCopyConstructors = true; + driver.Options.MarshalCharAsManagedChar = true; + driver.Options.GenerateProperties = true; + driver.Options.GenerateConversionOperators = true; + } + + public override void Preprocess(Driver driver, ASTContext ctx) + { + ctx.SetClassAsValueType("HasQList"); + ctx.FindCompleteClass("QList").Constructors.First(c => c.IsCopyConstructor).GenerationKind = GenerationKind.None; + ctx.IgnoreClassWithName("IgnoredType"); + } + + public static void Main(string[] args) + { + ConsoleDriver.Run(new TypeMaps(GeneratorKind.CLI)); + ConsoleDriver.Run(new TypeMaps(GeneratorKind.CSharp)); + } + } +} diff --git a/tests/TypeMaps/TypeMaps.h b/tests/TypeMaps/TypeMaps.h new file mode 100644 index 00000000..f09257f5 --- /dev/null +++ b/tests/TypeMaps/TypeMaps.h @@ -0,0 +1,16 @@ +#include "../Tests.h" + +class DLL_API QList +{ +public: + QList(); + int i; +}; + +class DLL_API HasQList +{ +public: + QList getList(); +private: + QList list; +}; diff --git a/tests/TypeMaps/premake4.lua b/tests/TypeMaps/premake4.lua new file mode 100644 index 00000000..df7f3f0d --- /dev/null +++ b/tests/TypeMaps/premake4.lua @@ -0,0 +1,2 @@ +group "Tests/TypeMaps" + SetupTestProject("TypeMaps") \ No newline at end of file