Browse Source

Extended the support for fixed arrays to the C++/CLI back-end.

Signed-off-by: Dimitar Dobrev <dpldobrev@yahoo.com>
pull/358/head
Dimitar Dobrev 11 years ago
parent
commit
261473cef8
  1. 36
      src/Generator/Generators/CLI/CLIMarshal.cs
  2. 28
      src/Generator/Generators/CLI/CLISourcesTemplate.cs
  3. 10
      tests/Basic/Basic.Tests.cs
  4. 1
      tests/Basic/Basic.h
  5. 10
      tests/CSharpTemp/CSharpTemp.Tests.cs
  6. 1
      tests/CSharpTemp/CSharpTemp.h

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

@ -45,7 +45,20 @@ namespace CppSharp.Generators.CLI
switch (array.SizeType) switch (array.SizeType)
{ {
case ArrayType.ArraySize.Constant: case ArrayType.ArraySize.Constant:
Context.Return.Write("nullptr"); var supportBefore = Context.SupportBefore;
string value = Generator.GeneratedIdentifier("array");
supportBefore.WriteLine("cli::array<{0}>^ {1} = nullptr;", array.Type, value, array.Size);
supportBefore.WriteLine("if ({0} != 0)", Context.ReturnVarName);
supportBefore.WriteStartBraceIndent();
supportBefore.WriteLine("{0} = gcnew cli::array<{1}>({2});", value, array.Type, array.Size);
supportBefore.WriteLine("for (int i = 0; i < {0}; i++)", array.Size);
if (array.Type.IsPointerToPrimitiveType(PrimitiveType.Void))
supportBefore.WriteLineIndent("{0}[i] = new ::System::IntPtr({1}[i]);",
value, Context.ReturnVarName);
else
supportBefore.WriteLineIndent("{0}[i] = {1}[i];", value, Context.ReturnVarName);
supportBefore.WriteCloseBraceIndent();
Context.Return.Write(value);
break; break;
case ArrayType.ArraySize.Variable: case ArrayType.ArraySize.Variable:
Context.Return.Write("nullptr"); Context.Return.Write("nullptr");
@ -412,7 +425,26 @@ namespace CppSharp.Generators.CLI
public override bool VisitArrayType(ArrayType array, TypeQualifiers quals) public override bool VisitArrayType(ArrayType array, TypeQualifiers quals)
{ {
return false; if (!VisitType(array, quals))
return false;
switch (array.SizeType)
{
case ArrayType.ArraySize.Constant:
var supportBefore = Context.SupportBefore;
supportBefore.WriteLine("if ({0} != nullptr)", Context.ArgName);
supportBefore.WriteStartBraceIndent();
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);
supportBefore.WriteCloseBraceIndent();
break;
default:
Context.Return.Write("null");
break;
}
return true;
} }
public override bool VisitFunctionType(FunctionType function, TypeQualifiers quals) public override bool VisitFunctionType(FunctionType function, TypeQualifiers quals)

28
src/Generator/Generators/CLI/CLISourcesTemplate.cs

@ -391,33 +391,37 @@ namespace CppSharp.Generators.CLI
QualifiedType = new QualifiedType(type) QualifiedType = new QualifiedType(type)
}; };
string variable;
if (decl is Variable)
variable = string.Format("::{0}::{1}",
@class.QualifiedOriginalName, decl.OriginalName);
else
variable = string.Format("((::{0}*)NativePtr)->{1}",
@class.QualifiedOriginalName, decl.OriginalName);
var ctx = new MarshalContext(Driver) var ctx = new MarshalContext(Driver)
{ {
Parameter = param, Parameter = param,
ArgName = param.Name, ArgName = param.Name,
ReturnVarName = variable
}; };
var marshal = new CLIMarshalManagedToNativePrinter(ctx); var marshal = new CLIMarshalManagedToNativePrinter(ctx);
param.Visit(marshal); param.Visit(marshal);
string variable;
if (decl is Variable)
variable = string.Format("::{0}::{1}",
@class.QualifiedOriginalName, decl.OriginalName);
else
variable = string.Format("((::{0}*)NativePtr)->{1}",
@class.QualifiedOriginalName, decl.OriginalName);
if (isIndexer) if (isIndexer)
variable += string.Format("({0})", indexParameter.Name); variable += string.Format("({0})", indexParameter.Name);
if (!string.IsNullOrWhiteSpace(marshal.Context.SupportBefore)) if (!string.IsNullOrWhiteSpace(marshal.Context.SupportBefore))
Write(marshal.Context.SupportBefore); Write(marshal.Context.SupportBefore);
if (isIndexer && decl.Type.IsPointer()) if (marshal.Context.Return.StringBuilder.Length > 0)
WriteLine("*({0}) = {1};", variable, marshal.Context.Return); {
else if (isIndexer && decl.Type.IsPointer())
WriteLine("{0} = {1};", variable, marshal.Context.Return); WriteLine("*({0}) = {1};", variable, marshal.Context.Return);
else
WriteLine("{0} = {1};", variable, marshal.Context.Return);
}
} }
WriteCloseBraceIndent(); WriteCloseBraceIndent();

10
tests/Basic/Basic.Tests.cs

@ -442,5 +442,15 @@ public class BasicTests : GeneratorTestFixture
{ {
new TestDelegates().MarshalUnattributedDelegate(i => i); new TestDelegates().MarshalUnattributedDelegate(i => i);
} }
[Test]
public void TestFixedArrays()
{
var foo = new Foo();
var array = new[] { 1, 2, 3 };
foo.fixedArray = array;
for (int i = 0; i < foo.fixedArray.Length; i++)
Assert.That(array[i], Is.EqualTo(foo.fixedArray[i]));
}
} }

1
tests/Basic/Basic.h

@ -29,6 +29,7 @@ public:
int A; int A;
float B; float B;
IgnoredType ignoredType; IgnoredType ignoredType;
int fixedArray[3];
const char* GetANSI(); const char* GetANSI();
// TODO: VC++ does not support char16 // TODO: VC++ does not support char16

10
tests/CSharpTemp/CSharpTemp.Tests.cs

@ -31,16 +31,6 @@ public class CSharpTempTests : GeneratorTestFixture
BindingFlags.Instance | BindingFlags.NonPublic), Is.Not.Null); BindingFlags.Instance | BindingFlags.NonPublic), Is.Not.Null);
} }
[Test]
public void TestFixedArrays()
{
Qux qux = new Qux((Foo) null);
var array = new[] { 1, 2, 3 };
qux.Array = array;
for (int i = 0; i < qux.Array.Length; i++)
Assert.That(array[i], Is.EqualTo(qux.Array[i]));
}
[Test] [Test]
public void TestMultipleInheritance() public void TestMultipleInheritance()
{ {

1
tests/CSharpTemp/CSharpTemp.h

@ -20,7 +20,6 @@ public:
Qux(); Qux();
Qux(Foo foo); Qux(Foo foo);
int farAwayFunc() const; int farAwayFunc() const;
int array[3];
void obsolete(); void obsolete();
}; };

Loading…
Cancel
Save