Browse Source

Merge pull request #539 from genuinelucifer/fixedArrayValueType

Added marshalling of fixed size non primitive type arrays.
pull/546/head
João Matos 10 years ago
parent
commit
1cb60c433b
  1. 21
      src/Generator/Generators/CSharp/CSharpMarshal.cs
  2. 4
      src/Generator/Passes/CheckIgnoredDecls.cs
  3. 29
      tests/CSharpTemp/CSharpTemp.Tests.cs
  4. 2
      tests/CSharpTemp/CSharpTemp.h

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

@ -111,6 +111,7 @@ namespace CppSharp.Generators.CSharp @@ -111,6 +111,7 @@ namespace CppSharp.Generators.CSharp
if (!VisitType(array, quals))
return false;
Class @class;
switch (array.SizeType)
{
case ArrayType.ArraySize.Constant:
@ -124,6 +125,9 @@ namespace CppSharp.Generators.CSharp @@ -124,6 +125,9 @@ namespace CppSharp.Generators.CSharp
if (array.Type.IsPointerToPrimitiveType(PrimitiveType.Void))
supportBefore.WriteLineIndent("{0}[i] = new global::System.IntPtr({1}[i]);",
value, Context.ReturnVarName);
else if (array.Type.Desugar().TryGetClass(out @class) && @class.IsRefType)
supportBefore.WriteLineIndent("{0}[i] = {1}.{2}(*(({1}.Internal*)&({3}[i * sizeof({1}.Internal)])));",
value, array.Type, Helpers.CreateInstanceIdentifier, Context.ReturnVarName);
else
supportBefore.WriteLineIndent("{0}[i] = {1}[i];", value, Context.ReturnVarName);
supportBefore.WriteCloseBraceIndent();
@ -382,16 +386,27 @@ namespace CppSharp.Generators.CSharp @@ -382,16 +386,27 @@ namespace CppSharp.Generators.CSharp
if (!VisitType(array, quals))
return false;
Class @class;
switch (array.SizeType)
{
case ArrayType.ArraySize.Constant:
var supportBefore = Context.SupportBefore;
supportBefore.WriteLine("if ({0} != null)", Context.ArgName);
supportBefore.WriteStartBraceIndent();
if (array.Type.Desugar().TryGetClass(out @class) && @class.IsRefType)
{
supportBefore.WriteLine("if (value.Length != {0})", array.Size);
supportBefore.WriteLineIndent("throw new ArgumentOutOfRangeException(\"{0}\", \"The provided array's dimensions doesn't match the required size.\");",
Context.Parameter.Name);
}
supportBefore.WriteLine("for (int i = 0; i < {0}; i++)", array.Size);
supportBefore.WriteLineIndent("{0}[i] = {1}[i]{2};",
Context.ReturnVarName, Context.ArgName,
array.Type.IsPointerToPrimitiveType(PrimitiveType.Void) ? ".ToPointer()" : string.Empty);
if (@class != null && @class.IsRefType)
supportBefore.WriteLineIndent("{0}[i * sizeof({2}.Internal)] = *((byte*)({2}.Internal*){1}[i].__Instance);",
Context.ReturnVarName, Context.ArgName, array.Type);
else
supportBefore.WriteLineIndent("{0}[i] = {1}[i]{2};",
Context.ReturnVarName, Context.ArgName,
array.Type.IsPointerToPrimitiveType(PrimitiveType.Void) ? ".ToPointer()" : string.Empty);
supportBefore.WriteCloseBraceIndent();
break;
default:

4
src/Generator/Passes/CheckIgnoredDecls.cs

@ -341,11 +341,13 @@ namespace CppSharp.Passes @@ -341,11 +341,13 @@ namespace CppSharp.Passes
return true;
}
Class @class;
var arrayType = type as ArrayType;
PrimitiveType primitive;
if (arrayType != null && arrayType.SizeType == ArrayType.ArraySize.Constant &&
!arrayType.Type.IsPrimitiveType(out primitive) &&
!arrayType.Type.Desugar().IsPointerToPrimitiveType())
!arrayType.Type.Desugar().IsPointerToPrimitiveType() &&
!(arrayType.Type.Desugar().TryGetClass(out @class) && @class.IsRefType))
{
msg = "unsupported";
return true;

29
tests/CSharpTemp/CSharpTemp.Tests.cs

@ -393,4 +393,33 @@ public class CSharpTempTests : GeneratorTestFixture @@ -393,4 +393,33 @@ public class CSharpTempTests : GeneratorTestFixture
obj.FuncPrimitivePtrToRefWithDefVal(ref refInt, null, null, ref refInt);
obj.FuncPrimitivePtrToRefWithMultiOverload(ref refInt, null, null, ref refInt);
}
[Test]
public void TestFixedArrayRefType()
{
Foo[] foos = new Foo[4];
foos[0] = new Foo();
foos[0].A = 5;
foos[1] = new Foo();
foos[1].A = 6;
foos[2] = new Foo();
foos[2].A = 7;
foos[3] = new Foo();
foos[3].A = 8;
Bar bar = new Bar();
bar.Foos = foos;
Foo[] retFoos = bar.Foos;
Assert.AreEqual(5, retFoos[0].A);
Assert.AreEqual(6, retFoos[1].A);
Assert.AreEqual(7, retFoos[2].A);
Assert.AreEqual(8, retFoos[3].A);
Foo[] foosMore = new Foo[2];
foosMore[0] = new Foo();
foosMore[1] = new Foo();
var ex = Assert.Throws<ArgumentOutOfRangeException>(() => bar.Foos = foosMore);
Assert.AreEqual("value", ex.ParamName);
Assert.AreEqual("The provided array's dimensions doesn't match the required size.\r\nParameter name: value", ex.Message);
}
}

2
tests/CSharpTemp/CSharpTemp.h

@ -65,11 +65,11 @@ public: @@ -65,11 +65,11 @@ public:
const Bar& operator++();
Bar operator++(int i);
void* arrayOfPrimitivePointers[1];
Foo foos[4];
private:
int index;
Foo m_foo;
Foo foos[4];
};
Bar::Bar() {}

Loading…
Cancel
Save