Browse Source

Added C# marshalling of parameters of type array of primitives.

Signed-off-by: Dimitar Dobrev <dpldobrev@protonmail.com>
pull/944/head
Dimitar Dobrev 9 years ago
parent
commit
ce71a3b8a8
  1. 3
      src/AST/ITypePrinter.cs
  2. 2
      src/Generator/Generators/CLI/CLIMarshal.cs
  3. 9
      src/Generator/Generators/CLI/CLITypeReferences.cs
  4. 9
      src/Generator/Generators/CSharp/CSharpMarshal.cs
  5. 28
      src/Generator/Generators/CSharp/CSharpSources.cs
  6. 6
      src/Generator/Generators/CSharp/CSharpTypePrinter.cs
  7. 3
      tests/CSharp/CSharp.Tests.cs
  8. 4
      tests/CSharp/CSharp.cpp
  9. 2
      tests/CSharp/CSharp.h

3
src/AST/ITypePrinter.cs

@ -19,7 +19,8 @@ namespace CppSharp.AST
GenericDelegate, GenericDelegate,
DefaultExpression, DefaultExpression,
VTableReturnValue, VTableReturnValue,
Variable Variable,
ReturnVariableArray
} }
public class TypePrinterContext public class TypePrinterContext

2
src/Generator/Generators/CLI/CLIMarshal.cs

@ -528,8 +528,6 @@ namespace CppSharp.Generators.CLI
if (pointee is FunctionType) if (pointee is FunctionType)
{ {
var function = pointee as FunctionType;
var cppTypePrinter = new CppTypePrinter(); var cppTypePrinter = new CppTypePrinter();
var cppTypeName = pointer.Visit(cppTypePrinter, quals); var cppTypeName = pointer.Visit(cppTypePrinter, quals);

9
src/Generator/Generators/CLI/CLITypeReferences.cs

@ -148,15 +148,6 @@ namespace CppSharp.Generators.CLI
} }
return translationUnit.FileName; return translationUnit.FileName;
var rel = PathHelpers.GetRelativePath(
TranslationUnit.FileRelativeDirectory,
translationUnit.FileRelativeDirectory);
if (string.IsNullOrEmpty(rel))
return translationUnit.FileName;
return Path.Combine(rel, translationUnit.FileName);
} }
private bool IsBuiltinTypedef(Declaration decl) private bool IsBuiltinTypedef(Declaration decl)

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

@ -555,10 +555,7 @@ namespace CppSharp.Generators.CSharp
} }
if (pointee is FunctionType) if (pointee is FunctionType)
{
var function = pointee as FunctionType;
return VisitDelegateType(); return VisitDelegateType();
}
Class @class; Class @class;
if (pointee.TryGetClass(out @class) && @class.IsValueType) if (pointee.TryGetClass(out @class) && @class.IsValueType)
@ -857,6 +854,12 @@ namespace CppSharp.Generators.CSharp
private void MarshalVariableArray(Type arrayType) private void MarshalVariableArray(Type arrayType)
{ {
if (arrayType.IsPrimitiveType())
{
Context.Return.Write(Context.Parameter.Name);
return;
}
var intermediateArray = $"__{Context.Parameter.Name}"; var intermediateArray = $"__{Context.Parameter.Name}";
var intermediateArrayType = typePrinter.PrintNative(arrayType); var intermediateArrayType = typePrinter.PrintNative(arrayType);
const string intPtrType = CSharpTypePrinter.IntPtrType; const string intPtrType = CSharpTypePrinter.IntPtrType;

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

@ -1028,21 +1028,28 @@ namespace CppSharp.Generators.CSharp
TypePrinter.PushContext(TypePrinterContextKind.Native); TypePrinter.PushContext(TypePrinterContextKind.Native);
var location = string.Format("CppSharp.SymbolResolver.ResolveSymbol(\"{0}\", \"{1}\")", string library = GetLibraryOf(decl);
GetLibraryOf(decl), var.Mangled); var location = $"CppSharp.SymbolResolver.ResolveSymbol(\"{library}\", \"{var.Mangled}\")";
var ptr = Generator.GeneratedIdentifier("ptr");
var arrayType = decl.Type as ArrayType; var arrayType = decl.Type as ArrayType;
var @class = decl.Namespace as Class; var @class = decl.Namespace as Class;
var isRefTypeArray = arrayType != null && @class != null && @class.IsRefType; var isRefTypeArray = arrayType != null && @class != null && @class.IsRefType;
if (isRefTypeArray) if (isRefTypeArray)
WriteLine("var {0} = {1}{2};", Generator.GeneratedIdentifier("ptr"), {
arrayType.Type.IsPrimitiveType(PrimitiveType.Char) && string cast = arrayType.Type.IsPrimitiveType(PrimitiveType.Char) &&
arrayType.QualifiedType.Qualifiers.IsConst arrayType.QualifiedType.Qualifiers.IsConst
? string.Empty : "(byte*)", ? string.Empty : "(byte*)";
location); WriteLine($"var {ptr} = {cast}{location};");
}
else else
WriteLine("var {0} = ({1}*){2};", Generator.GeneratedIdentifier("ptr"), {
@var.Type, location); TypePrinter.PushMarshalKind(MarshalKind.ReturnVariableArray);
var varType = var.Type.Visit(TypePrinter);
TypePrinter.PopMarshalKind();
WriteLine($"var {ptr} = ({varType}*){location};");
}
TypePrinter.PopContext(); TypePrinter.PopContext();
@ -1322,7 +1329,10 @@ namespace CppSharp.Generators.CSharp
PushBlock(BlockKind.Variable); PushBlock(BlockKind.Variable);
GenerateDeclarationCommon(variable); GenerateDeclarationCommon(variable);
WriteLine("public static {0} {1}", variable.Type, variable.Name); TypePrinter.PushMarshalKind(MarshalKind.ReturnVariableArray);
var variableType = variable.Type.Visit(TypePrinter);
TypePrinter.PopMarshalKind();
WriteLine($"public static {variableType} {variable.Name}");
WriteStartBraceIndent(); WriteStartBraceIndent();
GeneratePropertyGetter(variable, @class); GeneratePropertyGetter(variable, @class);

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

@ -128,9 +128,9 @@ namespace CppSharp.Generators.CSharp
if (arrayType.IsPointerToPrimitiveType(PrimitiveType.Char)) if (arrayType.IsPointerToPrimitiveType(PrimitiveType.Char))
return "char**"; return "char**";
var arraySuffix = array.SizeType == ArrayType.ArraySize.Constant || var arraySuffix = array.SizeType != ArrayType.ArraySize.Constant &&
!arrayType.IsPrimitiveType() ? "[]" : MarshalKind == MarshalKind.ReturnVariableArray ?
(ContextKind == TypePrinterContextKind.Managed ? "*" : string.Empty); (ContextKind == TypePrinterContextKind.Managed ? "*" : string.Empty) : "[]";
return $"{arrayType.Visit(this)}{arraySuffix}"; return $"{arrayType.Visit(this)}{arraySuffix}";
} }

3
tests/CSharp/CSharp.Tests.cs

@ -1064,7 +1064,8 @@ public unsafe class CSharpTests : GeneratorTestFixture
public void TestArrayParams() public void TestArrayParams()
{ {
Foo[] foos = { new Foo { A = 2 }, new Foo { A = 5 } }; Foo[] foos = { new Foo { A = 2 }, new Foo { A = 5 } };
Assert.That(CSharp.CSharp.TakeArrayOfPointersToObjects(foos), Is.EqualTo(7)); int[] ints = { 6, 7 };
Assert.That(CSharp.CSharp.TakeArrays(foos, ints), Is.EqualTo(20));
} }
private class OverrideVirtualTemplate : VirtualTemplate<int> private class OverrideVirtualTemplate : VirtualTemplate<int>

4
tests/CSharp/CSharp.cpp

@ -1392,7 +1392,7 @@ void InlineNamespace::FunctionInsideInlineNamespace()
{ {
} }
int takeArrayOfPointersToObjects(Foo* arrayOfPointersToObjects[]) int takeArrays(Foo* arrayOfPointersToObjects[], int arrayOfPrimitives[])
{ {
return arrayOfPointersToObjects[0]->A + arrayOfPointersToObjects[1]->A; return arrayOfPointersToObjects[0]->A + arrayOfPointersToObjects[1]->A + arrayOfPrimitives[0] + arrayOfPrimitives[1];
} }

2
tests/CSharp/CSharp.h

@ -1237,4 +1237,4 @@ inline namespace InlineNamespace
DLL_API void FunctionInsideInlineNamespace(); DLL_API void FunctionInsideInlineNamespace();
} }
DLL_API int takeArrayOfPointersToObjects(Foo* arrayOfPointersToObjects[]); DLL_API int takeArrays(Foo* arrayOfPointersToObjects[], int arrayOfPrimitives[]);

Loading…
Cancel
Save