Browse Source

Fixed the generated C# for fixed arrays in types of parameters.

Signed-off-by: Dimitar Dobrev <dpldobrev@protonmail.com>
pull/955/head
Dimitar Dobrev 8 years ago
parent
commit
3af63fb33d
  1. 31
      src/Generator/Generators/CSharp/CSharpMarshal.cs
  2. 7
      src/Generator/Generators/CSharp/CSharpTypePrinter.cs
  3. 2
      src/Generator/Passes/CheckIgnoredDecls.cs
  4. 30
      src/Generator/Types/TypeIgnoreChecker.cs
  5. 8
      tests/CSharp/CSharp.cpp
  6. 2
      tests/CSharp/CSharp.h

31
src/Generator/Generators/CSharp/CSharpMarshal.cs

@ -478,15 +478,7 @@ namespace CppSharp.Generators.CSharp @@ -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 @@ -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 @@ -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 @@ -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({

7
src/Generator/Generators/CSharp/CSharpTypePrinter.cs

@ -60,7 +60,9 @@ namespace CppSharp.Generators.CSharp @@ -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 @@ -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;

2
src/Generator/Passes/CheckIgnoredDecls.cs

@ -472,7 +472,7 @@ namespace CppSharp.Passes @@ -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;

30
src/Generator/Types/TypeIgnoreChecker.cs

@ -1,5 +1,6 @@ @@ -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 @@ -9,14 +10,16 @@ namespace CppSharp
/// </summary>
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 @@ -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 @@ -170,6 +188,8 @@ namespace CppSharp
Ignore();
return false;
}
}
private readonly GeneratorKind generatorKind;
}
}

8
tests/CSharp/CSharp.cpp

@ -1407,6 +1407,14 @@ int TestArrays::takeArrays(Foo* arrayOfPointersToObjects[], int arrayOfPrimitive @@ -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;

2
tests/CSharp/CSharp.h

@ -1243,6 +1243,8 @@ public: @@ -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;

Loading…
Cancel
Save