diff --git a/src/Generator/Generators/CSharp/CSharpMarshal.cs b/src/Generator/Generators/CSharp/CSharpMarshal.cs index c570c60c..ec5b5926 100644 --- a/src/Generator/Generators/CSharp/CSharpMarshal.cs +++ b/src/Generator/Generators/CSharp/CSharpMarshal.cs @@ -478,15 +478,7 @@ namespace CppSharp.Generators.CSharp case ArrayType.ArraySize.Constant: if (string.IsNullOrEmpty(Context.ReturnVarName)) { - Context.Before.WriteLine("if ({0} == null || {0}.Length != {1})", - Context.Parameter.Name, array.Size); - ThrowArgumentOutOfRangeException(); - var ptr = "__ptr" + Context.ParameterIndex; - Context.Before.WriteLine("fixed ({0}* {1} = {2})", - array.Type, ptr, Context.Parameter.Name); - Context.Before.WriteStartBraceIndent(); - Context.Return.Write("new global::System.IntPtr({0})", ptr); - Context.HasCodeBlock = true; + goto case ArrayType.ArraySize.Incomplete; } else { @@ -530,7 +522,7 @@ namespace CppSharp.Generators.CSharp } break; case ArrayType.ArraySize.Incomplete: - MarshalVariableArray(arrayType); + MarshalArray(array); break; default: Context.Return.Write("null"); @@ -898,17 +890,26 @@ namespace CppSharp.Generators.CSharp Context.Parameter.Name); } - private void MarshalVariableArray(Type arrayType) + private void MarshalArray(ArrayType arrayType) { - if (arrayType.IsPrimitiveType() || - arrayType.IsPointerToPrimitiveType(PrimitiveType.Char)) + if (arrayType.SizeType == ArrayType.ArraySize.Constant) + { + Context.Before.WriteLine("if ({0} == null || {0}.Length != {1})", + Context.Parameter.Name, arrayType.Size); + ThrowArgumentOutOfRangeException(); + } + + var elementType = arrayType.Type.Desugar(); + + if (elementType.IsPrimitiveType() || + elementType.IsPointerToPrimitiveType()) { Context.Return.Write(Context.Parameter.Name); return; } var intermediateArray = Generator.GeneratedIdentifier(Context.Parameter.Name); - var intermediateArrayType = typePrinter.PrintNative(arrayType); + var intermediateArrayType = typePrinter.PrintNative(elementType); Context.Before.WriteLine($"{intermediateArrayType}[] {intermediateArray};"); @@ -924,7 +925,7 @@ namespace CppSharp.Generators.CSharp Context.Before.WriteStartBraceIndent(); string element = Generator.GeneratedIdentifier("element"); Context.Before.WriteLine($"var {element} = {Context.Parameter.Name}[i];"); - if (arrayType.IsAddress()) + if (elementType.IsAddress()) { var intPtrZero = $"{CSharpTypePrinter.IntPtrType}.Zero"; Context.Before.WriteLine($@"{intermediateArray}[i] = ReferenceEquals({ diff --git a/src/Generator/Generators/CSharp/CSharpTypePrinter.cs b/src/Generator/Generators/CSharp/CSharpTypePrinter.cs index 8a1225da..b8471a8a 100644 --- a/src/Generator/Generators/CSharp/CSharpTypePrinter.cs +++ b/src/Generator/Generators/CSharp/CSharpTypePrinter.cs @@ -60,7 +60,9 @@ namespace CppSharp.Generators.CSharp TypeQualifiers quals) { Type arrayType = array.Type.Desugar(); - if (ContextKind == TypePrinterContextKind.Native && + if ((MarshalKind == MarshalKind.NativeField || + (ContextKind == TypePrinterContextKind.Native && + MarshalKind == MarshalKind.ReturnVariableArray)) && array.SizeType == ArrayType.ArraySize.Constant) { if (array.Size == 0) @@ -278,8 +280,7 @@ namespace CppSharp.Generators.CSharp } Class @class; - if ((desugared.IsDependent || desugared.TryGetClass(out @class) || - (desugared is ArrayType && Parameter != null)) + if ((desugared.IsDependent || desugared.TryGetClass(out @class)) && ContextKind == TypePrinterContextKind.Native) { return IntPtrType; diff --git a/src/Generator/Passes/CheckIgnoredDecls.cs b/src/Generator/Passes/CheckIgnoredDecls.cs index 06de9482..cf259c85 100644 --- a/src/Generator/Passes/CheckIgnoredDecls.cs +++ b/src/Generator/Passes/CheckIgnoredDecls.cs @@ -472,7 +472,7 @@ namespace CppSharp.Passes private bool IsTypeIgnored(Type type) { - var checker = new TypeIgnoreChecker(TypeMaps); + var checker = new TypeIgnoreChecker(TypeMaps, Options.GeneratorKind); type.Visit(checker); return checker.IsIgnored; diff --git a/src/Generator/Types/TypeIgnoreChecker.cs b/src/Generator/Types/TypeIgnoreChecker.cs index a9582aaf..8dcae3e0 100644 --- a/src/Generator/Types/TypeIgnoreChecker.cs +++ b/src/Generator/Types/TypeIgnoreChecker.cs @@ -1,5 +1,6 @@ using CppSharp.AST; using CppSharp.AST.Extensions; +using CppSharp.Generators; using CppSharp.Types; namespace CppSharp @@ -9,14 +10,16 @@ namespace CppSharp /// public class TypeIgnoreChecker : AstVisitor { - ITypeMapDatabase TypeMapDatabase { get; set; } + ITypeMapDatabase TypeMapDatabase { get; } public bool IsIgnored; - public TypeIgnoreChecker(ITypeMapDatabase database) + public TypeIgnoreChecker(ITypeMapDatabase database, + GeneratorKind generatorKind = GeneratorKind.CSharp) { TypeMapDatabase = database; VisitOptions.VisitClassBases = false; VisitOptions.VisitTemplateArguments = false; + this.generatorKind = generatorKind; } void Ignore() @@ -138,14 +141,29 @@ namespace CppSharp return false; } + var arrayElemType = array.Type.Desugar(); + Enumeration @enum; + FunctionType functionType; + if (arrayElemType is ArrayType || + arrayElemType is FunctionType || + arrayElemType.IsPointerTo(out functionType) || + (arrayElemType.TryGetEnum(out @enum) && + array.SizeType == ArrayType.ArraySize.Constant)) + { + Ignore(); + return false; + } + + if (generatorKind == GeneratorKind.CSharp) + return true; + + // the C++/CLI generator needs work to support arrays if (!array.QualifiedType.Visit(this)) return false; if (array.SizeType != ArrayType.ArraySize.Constant) return true; - var arrayElemType = array.Type.Desugar(); - Class @class; if (arrayElemType.TryGetClass(out @class) && @class.IsRefType) return true; @@ -170,6 +188,8 @@ namespace CppSharp Ignore(); return false; } - } + + private readonly GeneratorKind generatorKind; + } } diff --git a/tests/CSharp/CSharp.cpp b/tests/CSharp/CSharp.cpp index e3f65660..a3596ec7 100644 --- a/tests/CSharp/CSharp.cpp +++ b/tests/CSharp/CSharp.cpp @@ -1407,6 +1407,14 @@ int TestArrays::takeArrays(Foo* arrayOfPointersToObjects[], int arrayOfPrimitive arrayOfObjects[0].A + arrayOfObjects[1].A; } +int TestArrays::takeArrays(Foo* fixedArrayOfPointersToObjects[3], int fixedArrayOfPrimitives[4], + int* fixedArrayOfPointersToPrimitives[5]) const +{ + return fixedArrayOfPointersToObjects[0]->A + fixedArrayOfPointersToObjects[1]->A + + fixedArrayOfPrimitives[0] + fixedArrayOfPrimitives[1] + + *fixedArrayOfPointersToPrimitives[0] + *fixedArrayOfPointersToPrimitives[1]; +} + std::string TestArrays::takeStringArray(const char* arrayOfStrings[]) { std::string result; diff --git a/tests/CSharp/CSharp.h b/tests/CSharp/CSharp.h index 2682a7cd..df383cd8 100644 --- a/tests/CSharp/CSharp.h +++ b/tests/CSharp/CSharp.h @@ -1243,6 +1243,8 @@ public: TestArrays(); ~TestArrays(); int takeArrays(Foo* arrayOfPointersToObjects[], int arrayOfPrimitives[], Foo arrayOfObjects[]) const; + int takeArrays(Foo* fixedArrayOfPointersToObjects[3], int fixedArrayOfPrimitives[4], + int* fixedArrayOfPointersToPrimitives[5]) const; std::string takeStringArray(const char* arrayOfStrings[]); std::string takeConstStringArray(const char* const arrayOfStrings[]); virtual int virtualTakesArrays(Foo* arrayOfPointersToObjects[], int arrayOfPrimitives[], Foo arrayOfObjects[]) const;