Browse Source

Added C# marshalling of parameters of type array of const char* const.

Fixes https://github.com/mono/CppSharp/issues/692.

Signed-off-by: Dimitar Dobrev <dpldobrev@protonmail.com>
pull/955/head
Dimitar Dobrev 8 years ago
parent
commit
6a15e51d76
  1. 16
      src/Generator/Generators/CSharp/CSharpSources.cs
  2. 3
      src/Generator/Generators/CSharp/CSharpTypePrinter.cs
  3. 12
      src/Generator/Types/TypeIgnoreChecker.cs
  4. 1
      tests/CSharp/CSharp.Tests.cs
  5. 5
      tests/CSharp/CSharp.cpp
  6. 2
      tests/CSharp/CSharp.h

16
src/Generator/Generators/CSharp/CSharpSources.cs

@ -1032,11 +1032,12 @@ namespace CppSharp.Generators.CSharp
Type varType = var.Type.Desugar(); Type varType = var.Type.Desugar();
var arrayType = varType as ArrayType; var arrayType = varType as ArrayType;
var elementType = arrayType?.Type.Desugar();
var @class = var.Namespace as Class; var @class = var.Namespace as Class;
var isRefTypeArray = arrayType != null && @class != null && @class.IsRefType; var isRefTypeArray = arrayType != null && @class != null && @class.IsRefType;
if (isRefTypeArray) if (isRefTypeArray)
{ {
string cast = arrayType.Type.IsPrimitiveType(PrimitiveType.Char) && string cast = elementType.IsPrimitiveType(PrimitiveType.Char) &&
arrayType.QualifiedType.Qualifiers.IsConst arrayType.QualifiedType.Qualifiers.IsConst
? string.Empty : "(byte*)"; ? string.Empty : "(byte*)";
WriteLine($"var {ptr} = {cast}{location};"); WriteLine($"var {ptr} = {cast}{location};");
@ -1054,11 +1055,18 @@ namespace CppSharp.Generators.CSharp
var ctx = new CSharpMarshalContext(Context) var ctx = new CSharpMarshalContext(Context)
{ {
ArgName = var.Name, ArgName = var.Name,
ReturnVarName = (isRefTypeArray ||
(arrayType != null && arrayType.Type.Desugar().IsPrimitiveType()) ? string.Empty : "*")
+ Generator.GeneratedIdentifier("ptr"),
ReturnType = new QualifiedType(var.Type) ReturnType = new QualifiedType(var.Type)
}; };
var prefix = string.Empty;
if (!isRefTypeArray && elementType == null)
ctx.ReturnVarName = $"*{ptr}";
else if (elementType == null || elementType.IsPrimitiveType() ||
arrayType.SizeType == ArrayType.ArraySize.Constant)
ctx.ReturnVarName = ptr;
else
ctx.ReturnVarName = $@"{elementType}.{
Helpers.CreateInstanceIdentifier}(new {
CSharpTypePrinter.IntPtrType}({ptr}))";
var marshal = new CSharpMarshalNativeToManagedPrinter(ctx); var marshal = new CSharpMarshalNativeToManagedPrinter(ctx);
var.QualifiedType.Visit(marshal); var.QualifiedType.Visit(marshal);

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

@ -134,7 +134,8 @@ namespace CppSharp.Generators.CSharp
var arraySuffix = array.SizeType != ArrayType.ArraySize.Constant && var arraySuffix = array.SizeType != ArrayType.ArraySize.Constant &&
MarshalKind == MarshalKind.ReturnVariableArray ? MarshalKind == MarshalKind.ReturnVariableArray ?
(ContextKind == TypePrinterContextKind.Managed ? "*" : string.Empty) : "[]"; (ContextKind == TypePrinterContextKind.Managed &&
arrayType.IsPrimitiveType() ? "*" : string.Empty) : "[]";
return $"{arrayType.Visit(this)}{arraySuffix}"; return $"{arrayType.Visit(this)}{arraySuffix}";
} }

12
src/Generator/Types/TypeIgnoreChecker.cs

@ -138,22 +138,14 @@ namespace CppSharp
return false; return false;
} }
var arrayElemType = array.Type.Desugar();
if (array.SizeType == ArrayType.ArraySize.Incomplete &&
array.QualifiedType.Qualifiers.IsConst &&
!arrayElemType.IsPrimitiveType())
{
Ignore();
return false;
}
if (!array.QualifiedType.Visit(this)) if (!array.QualifiedType.Visit(this))
return false; return false;
if (array.SizeType != ArrayType.ArraySize.Constant) if (array.SizeType != ArrayType.ArraySize.Constant)
return true; return true;
var arrayElemType = array.Type.Desugar();
Class @class; Class @class;
if (arrayElemType.TryGetClass(out @class) && @class.IsRefType) if (arrayElemType.TryGetClass(out @class) && @class.IsRefType)
return true; return true;

1
tests/CSharp/CSharp.Tests.cs

@ -1074,6 +1074,7 @@ public unsafe class CSharpTests : GeneratorTestFixture
{ {
string[] strings = { "The ", "test ", "works." }; string[] strings = { "The ", "test ", "works." };
Assert.That(CSharp.CSharp.TakeStringArray(strings), Is.EqualTo("The test works.")); Assert.That(CSharp.CSharp.TakeStringArray(strings), Is.EqualTo("The test works."));
Assert.That(CSharp.CSharp.TakeConstStringArray(strings), Is.EqualTo("The test works."));
} }
private class OverrideVirtualTemplate : VirtualTemplate<int> private class OverrideVirtualTemplate : VirtualTemplate<int>

5
tests/CSharp/CSharp.cpp

@ -1408,3 +1408,8 @@ std::string takeStringArray(const char* arrayOfStrings[])
} }
return result; return result;
} }
std::string takeConstStringArray(const char* const arrayOfStrings[])
{
return takeStringArray(const_cast<const char**>(arrayOfStrings));
}

2
tests/CSharp/CSharp.h

@ -1240,3 +1240,5 @@ inline namespace InlineNamespace
DLL_API int takeArrays(Foo* arrayOfPointersToObjects[], int arrayOfPrimitives[], Foo arrayOfObjects[]); DLL_API int takeArrays(Foo* arrayOfPointersToObjects[], int arrayOfPrimitives[], Foo arrayOfObjects[]);
DLL_API std::string takeStringArray(const char* arrayOfStrings[]); DLL_API std::string takeStringArray(const char* arrayOfStrings[]);
DLL_API std::string takeConstStringArray(const char* const arrayOfStrings[]);

Loading…
Cancel
Save