diff --git a/src/Generator/Generators/CSharp/CSharpMarshal.cs b/src/Generator/Generators/CSharp/CSharpMarshal.cs index 8a4b7bb7..dc732ea1 100644 --- a/src/Generator/Generators/CSharp/CSharpMarshal.cs +++ b/src/Generator/Generators/CSharp/CSharpMarshal.cs @@ -169,6 +169,8 @@ namespace CppSharp.Generators.CSharp return true; } + if (Context.Driver.Options.MarshalCharAsManagedChar && primitive == PrimitiveType.Char) + Context.Return.Write(string.Format("({0}) ", pointer)); Context.Return.Write(Context.ReturnVarName); return true; } @@ -197,9 +199,6 @@ namespace CppSharp.Generators.CSharp return string.Format( "CppSharp.Runtime.Helpers.MarshalEncodedString({0}, {1})", varName, encodingName); - - throw new NotSupportedException(string.Format("{0} is not supported yet.", - Context.Driver.Options.Encoding.EncodingName)); } public override bool VisitPrimitiveType(PrimitiveType primitive, TypeQualifiers quals) @@ -208,28 +207,16 @@ namespace CppSharp.Generators.CSharp { case PrimitiveType.Void: return true; - case PrimitiveType.Bool: case PrimitiveType.Char: - case PrimitiveType.UChar: - case PrimitiveType.Short: - case PrimitiveType.UShort: - case PrimitiveType.Int: - case PrimitiveType.UInt: - case PrimitiveType.Long: - case PrimitiveType.ULong: - case PrimitiveType.LongLong: - case PrimitiveType.ULongLong: - case PrimitiveType.Float: - case PrimitiveType.Double: - case PrimitiveType.WideChar: - case PrimitiveType.Null: - Context.Return.Write(Context.ReturnVarName); - return true; + if (Context.Driver.Options.MarshalCharAsManagedChar) + Context.Return.Write("(char) "); + goto default; case PrimitiveType.Char16: return false; + default: + Context.Return.Write(Context.ReturnVarName); + return true; } - - throw new NotImplementedException(); } public override bool VisitTypedefType(TypedefType typedef, TypeQualifiers quals) @@ -508,7 +495,15 @@ namespace CppSharp.Generators.CSharp Context.Return.Write("&_{0}", param.Name); } else + { + if (Context.Driver.Options.MarshalCharAsManagedChar && primitive == PrimitiveType.Char) + { + var typePrinter = new CSharpTypePrinter(Context.Driver); + typePrinter.PushContext(CSharpTypePrinterContextKind.Native); + Context.Return.Write(string.Format("({0}) ", pointer.Visit(typePrinter))); + } Context.Return.Write(Context.Parameter.Name); + } return true; } @@ -537,27 +532,16 @@ namespace CppSharp.Generators.CSharp { case PrimitiveType.Void: return true; - case PrimitiveType.Bool: case PrimitiveType.Char: - case PrimitiveType.UChar: - case PrimitiveType.Short: - case PrimitiveType.UShort: - case PrimitiveType.Int: - case PrimitiveType.UInt: - case PrimitiveType.Long: - case PrimitiveType.ULong: - case PrimitiveType.LongLong: - case PrimitiveType.ULongLong: - case PrimitiveType.Float: - case PrimitiveType.Double: - case PrimitiveType.WideChar: - Context.Return.Write(Context.Parameter.Name); - return true; + if (Context.Driver.Options.MarshalCharAsManagedChar) + Context.Return.Write("(sbyte) "); + goto default; case PrimitiveType.Char16: return false; + default: + Context.Return.Write(Context.Parameter.Name); + return true; } - - throw new NotImplementedException(); } public override bool VisitTypedefType(TypedefType typedef, TypeQualifiers quals) diff --git a/src/Generator/Generators/CSharp/CSharpTextTemplate.cs b/src/Generator/Generators/CSharp/CSharpTextTemplate.cs index ef9bd316..8acda1cb 100644 --- a/src/Generator/Generators/CSharp/CSharpTextTemplate.cs +++ b/src/Generator/Generators/CSharp/CSharpTextTemplate.cs @@ -880,14 +880,7 @@ namespace CppSharp.Generators.CSharp if (arrayType != null && @class.IsValueType) { - CSharpTypePrinter typePrinter = new CSharpTypePrinter(ctx.Driver); - string type = arrayType.CSharpType(typePrinter).Type; - string arrPtrIden = Helpers.SafeIdentifier("arrPtr"); - WriteLine(string.Format("fixed ({0} {1} = {2}.{3})", - type.Replace("[]", "*"), arrPtrIden, Helpers.InstanceField, - Helpers.SafeIdentifier(field.InternalName))); - WriteStartBraceIndent(); - ctx.ReturnVarName = arrPtrIden; + ctx.ReturnVarName = HandleValueArray(arrayType, field); } else { @@ -917,6 +910,36 @@ namespace CppSharp.Generators.CSharp PopBlock(NewLineKind.BeforeNextBlock); } + private string HandleValueArray(ArrayType arrayType, Field field) + { + var originalType = new PointerType(new QualifiedType(arrayType.Type)); + var arrPtrIden = Generator.GeneratedIdentifier("arrPtr"); + var arrPtr = arrPtrIden; + var finalElementType = (arrayType.Type.GetFinalPointee() ?? arrayType.Type); + var isChar = finalElementType.IsPrimitiveType(PrimitiveType.Char); + + string type; + if (Driver.Options.MarshalCharAsManagedChar && isChar) + { + var typePrinter = new CSharpTypePrinter(Driver); + typePrinter.PushContext(CSharpTypePrinterContextKind.Native); + type = originalType.Visit(typePrinter).Type; + arrPtrIden = Generator.GeneratedIdentifier(arrPtrIden); + } + else + { + type = originalType.ToString(); + } + + WriteLine(string.Format("fixed ({0} {1} = {2}.{3})", + type, arrPtrIden, Helpers.InstanceField, + Helpers.SafeIdentifier(field.InternalName))); + WriteStartBraceIndent(); + if (Driver.Options.MarshalCharAsManagedChar && isChar) + WriteLine("var {0} = ({1}) {2};", arrPtr, originalType, arrPtrIden); + return arrPtr; + } + private bool WrapSetterArrayOfPointers(string name, Type fieldType) { var arrayType = fieldType as ArrayType; @@ -1005,16 +1028,7 @@ namespace CppSharp.Generators.CSharp var arrayType = field.Type as ArrayType; if (arrayType != null && @class.IsValueType) - { - CSharpTypePrinter typePrinter = new CSharpTypePrinter(ctx.Driver); - string type = arrayType.CSharpType(typePrinter).Type; - string arrPtrIden = Helpers.SafeIdentifier("arrPtr"); - WriteLine(string.Format("fixed ({0} {1} = {2}.{3})", - type.Replace("[]","*"), arrPtrIden, Helpers.InstanceField, - Helpers.SafeIdentifier(field.InternalName))); - WriteStartBraceIndent(); - ctx.ReturnVarName = arrPtrIden; - } + ctx.ReturnVarName = HandleValueArray(arrayType, field); var marshal = new CSharpMarshalNativeToManagedPrinter(ctx); decl.CSharpMarshalToManaged(marshal); @@ -2642,11 +2656,6 @@ namespace CppSharp.Generators.CSharp private ParamMarshal GenerateFunctionParamMarshal(Parameter param, int paramIndex, Function function = null) { - if (param.Type is BuiltinType) - { - return new ParamMarshal { Name = param.Name, Param = param }; - } - var argName = "arg" + paramIndex.ToString(CultureInfo.InvariantCulture); var paramMarshal = new ParamMarshal { Name = argName, Param = param }; diff --git a/src/Generator/Generators/CSharp/CSharpTypePrinter.cs b/src/Generator/Generators/CSharp/CSharpTypePrinter.cs index 9a8178ec..ab080998 100644 --- a/src/Generator/Generators/CSharp/CSharpTypePrinter.cs +++ b/src/Generator/Generators/CSharp/CSharpTypePrinter.cs @@ -483,7 +483,11 @@ namespace CppSharp.Generators.CSharp case PrimitiveType.Void: return "void"; case PrimitiveType.Char16: case PrimitiveType.WideChar: return "char"; - case PrimitiveType.Char: return this.driver.Options.MarshalCharAsManagedChar ? "char" : "sbyte"; + case PrimitiveType.Char: + return driver.Options.MarshalCharAsManagedChar && + ContextKind != CSharpTypePrinterContextKind.Native + ? "char" + : "sbyte"; case PrimitiveType.UChar: return "byte"; case PrimitiveType.Short: case PrimitiveType.UShort: diff --git a/tests/Common/Common.Tests.cs b/tests/Common/Common.Tests.cs index 9b29021a..c28fcd2e 100644 --- a/tests/Common/Common.Tests.cs +++ b/tests/Common/Common.Tests.cs @@ -534,5 +534,13 @@ public class CommonTests : GeneratorTestFixture common.funcTryValTypeOut(out valueTypeClassPassTry); common.funcTryValTypePtrOut(out valueTypeClassPassTry); } + + [Test] + public void TestVirtualReturningClassWithCharField() + { + using (new HasVirtualReturningHasCharField()) + { + } + } } \ No newline at end of file diff --git a/tests/Common/Common.cpp b/tests/Common/Common.cpp index 98cf57f5..42cba118 100644 --- a/tests/Common/Common.cpp +++ b/tests/Common/Common.cpp @@ -500,3 +500,12 @@ void funcTryValTypePtrOut(CS_OUT ValueTypeClassPassTry* classTry) void funcTryValTypeOut(CS_OUT ValueTypeClassPassTry classTry) { } + +HasVirtualReturningHasCharField::HasVirtualReturningHasCharField() +{ +} + +HasCharField HasVirtualReturningHasCharField::returnsCharField() +{ + return HasCharField(); +} diff --git a/tests/Common/Common.h b/tests/Common/Common.h index 0b1fffea..afc49575 100644 --- a/tests/Common/Common.h +++ b/tests/Common/Common.h @@ -804,3 +804,15 @@ class DLL_API CS_VALUE_TYPE ValueTypeClassPassTry { }; void DLL_API funcTryValTypePtrOut(CS_OUT ValueTypeClassPassTry* classTry); void DLL_API funcTryValTypeOut(CS_OUT ValueTypeClassPassTry classTry); + +class DLL_API HasCharField +{ + char c; +}; + +class DLL_API HasVirtualReturningHasCharField +{ +public: + HasVirtualReturningHasCharField(); + virtual HasCharField returnsCharField(); +};