Browse Source

Use List<IntPtr> when mapping a std::vector<T*> where T is a primitive type.

Pointers are not allowed in generic arguments.
pull/236/head
Elias Holzer 11 years ago
parent
commit
911ce43e07
  1. 5
      src/Generator/Generators/CLI/CLITypePrinter.cs
  2. 5
      src/Generator/Types/ITypePrinter.cs
  3. 27
      src/Generator/Types/Std/Stdlib.cs
  4. 33
      tests/STL/STL.Tests.cs
  5. 11
      tests/STL/STL.cpp
  6. 1
      tests/STL/STL.cs
  7. 22
      tests/STL/STL.h

5
src/Generator/Generators/CLI/CLITypePrinter.cs

@ -284,7 +284,10 @@ namespace CppSharp.Generators.CLI
public string VisitCILType(CILType type, TypeQualifiers quals) public string VisitCILType(CILType type, TypeQualifiers quals)
{ {
return type.Type.FullName.Replace(".", "::") + "^"; var result = type.Type.FullName.Replace(".", "::");
if (!type.Type.IsValueType)
result += "^";
return result;
} }
public string VisitPrimitiveType(PrimitiveType type, TypeQualifiers quals) public string VisitPrimitiveType(PrimitiveType type, TypeQualifiers quals)

5
src/Generator/Types/ITypePrinter.cs

@ -39,7 +39,10 @@ namespace CppSharp.Types
{ {
if (arg.Kind != TemplateArgument.ArgumentKind.Type) if (arg.Kind != TemplateArgument.ArgumentKind.Type)
continue; continue;
paramsList.Add(arg.Type.ToString()); var argType = arg.Type.Type.IsPointerToPrimitiveType()
? new CILType(typeof(System.IntPtr))
: arg.Type.Type;
paramsList.Add(argType.ToString());
} }
} }

27
src/Generator/Types/Std/Stdlib.cs

@ -1,4 +1,5 @@
using CppSharp.AST; using CppSharp.AST;
using CppSharp.AST.Extensions;
using CppSharp.Generators; using CppSharp.Generators;
using CppSharp.Generators.CLI; using CppSharp.Generators.CLI;
using CppSharp.Generators.CSharp; using CppSharp.Generators.CSharp;
@ -113,6 +114,10 @@ namespace CppSharp.Types.Std
{ {
var templateType = Type as TemplateSpecializationType; var templateType = Type as TemplateSpecializationType;
var type = templateType.Arguments[0].Type; var type = templateType.Arguments[0].Type;
var isPointerToPrimitive = type.Type.IsPointerToPrimitiveType();
var managedType = isPointerToPrimitive
? new CILType(typeof(System.IntPtr))
: type.Type;
var entryString = (ctx.Parameter != null) ? ctx.Parameter.Name var entryString = (ctx.Parameter != null) ? ctx.Parameter.Name
: ctx.ArgName; : ctx.ArgName;
@ -125,7 +130,7 @@ namespace CppSharp.Types.Std
ctx.SupportBefore.WriteLine("auto {0} = std::vector<{1}>();", ctx.SupportBefore.WriteLine("auto {0} = std::vector<{1}>();",
tmpVarName, nativeType); tmpVarName, nativeType);
ctx.SupportBefore.WriteLine("for each({0} _element in {1})", ctx.SupportBefore.WriteLine("for each({0} _element in {1})",
type.ToString(), entryString); managedType, entryString);
ctx.SupportBefore.WriteStartBraceIndent(); ctx.SupportBefore.WriteStartBraceIndent();
{ {
var param = new Parameter var param = new Parameter
@ -146,7 +151,11 @@ namespace CppSharp.Types.Std
if (!string.IsNullOrWhiteSpace(marshal.Context.SupportBefore)) if (!string.IsNullOrWhiteSpace(marshal.Context.SupportBefore))
ctx.SupportBefore.Write(marshal.Context.SupportBefore); ctx.SupportBefore.Write(marshal.Context.SupportBefore);
ctx.SupportBefore.WriteLine("auto _marshalElement = {0};", if (isPointerToPrimitive)
ctx.SupportBefore.WriteLine("auto _marshalElement = {0}.ToPointer();",
marshal.Context.Return);
else
ctx.SupportBefore.WriteLine("auto _marshalElement = {0};",
marshal.Context.Return); marshal.Context.Return);
ctx.SupportBefore.WriteLine("{0}.push_back(_marshalElement);", ctx.SupportBefore.WriteLine("{0}.push_back(_marshalElement);",
@ -162,11 +171,15 @@ namespace CppSharp.Types.Std
{ {
var templateType = Type as TemplateSpecializationType; var templateType = Type as TemplateSpecializationType;
var type = templateType.Arguments[0].Type; var type = templateType.Arguments[0].Type;
var isPointerToPrimitive = type.Type.IsPointerToPrimitiveType();
var managedType = isPointerToPrimitive
? new CILType(typeof(System.IntPtr))
: type.Type;
var tmpVarName = "_tmp" + ctx.ArgName; var tmpVarName = "_tmp" + ctx.ArgName;
ctx.SupportBefore.WriteLine( ctx.SupportBefore.WriteLine(
"auto {0} = gcnew System::Collections::Generic::List<{1}>();", "auto {0} = gcnew System::Collections::Generic::List<{1}>();",
tmpVarName, type.ToString()); tmpVarName, managedType);
ctx.SupportBefore.WriteLine("for(auto _element : {0})", ctx.SupportBefore.WriteLine("for(auto _element : {0})",
ctx.ReturnVarName); ctx.ReturnVarName);
ctx.SupportBefore.WriteStartBraceIndent(); ctx.SupportBefore.WriteStartBraceIndent();
@ -186,8 +199,12 @@ namespace CppSharp.Types.Std
ctx.SupportBefore.WriteLine("auto _marshalElement = {0};", ctx.SupportBefore.WriteLine("auto _marshalElement = {0};",
marshal.Context.Return); marshal.Context.Return);
ctx.SupportBefore.WriteLine("{0}->Add(_marshalElement);", if (isPointerToPrimitive)
tmpVarName); ctx.SupportBefore.WriteLine("{0}->Add({1}(_marshalElement));",
tmpVarName, managedType);
else
ctx.SupportBefore.WriteLine("{0}->Add(_marshalElement);",
tmpVarName);
} }
ctx.SupportBefore.WriteCloseBraceIndent(); ctx.SupportBefore.WriteCloseBraceIndent();

33
tests/STL/STL.Tests.cs

@ -1,7 +1,10 @@
using System.Collections.Generic; using System;
using System.Collections.Generic;
using System.Linq; using System.Linq;
using CppSharp.Utils; using CppSharp.Utils;
using NUnit.Framework; using NUnit.Framework;
using System.Runtime.InteropServices;
using STL;
public class STLTests : GeneratorTestFixture public class STLTests : GeneratorTestFixture
{ {
@ -15,6 +18,34 @@ public class STLTests : GeneratorTestFixture
var list = vectors.GetIntVector(); var list = vectors.GetIntVector();
Assert.True(list.SequenceEqual(new List<int> { 2, 3, 4 })); Assert.True(list.SequenceEqual(new List<int> { 2, 3, 4 }));
var ptrList = vectors.IntPtrVector;
var intList = ptrList.Select(ptr => Marshal.ReadInt32(ptr));
Assert.True(intList.SequenceEqual(new List<int> { 2, 3, 4 }));
var wrapperList = new List<IntWrapper>();
for (int i = 0; i < 3; i++)
wrapperList.Add(new IntWrapper() { Value = i });
vectors.IntWrapperVector = wrapperList;
wrapperList = vectors.IntWrapperVector;
for (int i = 0; i < 3; i++)
Assert.AreEqual(i, wrapperList[i].Value);
for (int i = 0; i < 3; i++)
wrapperList[i].Value += i;
vectors.IntWrapperPtrVector = wrapperList;
wrapperList = vectors.IntWrapperPtrVector;
for (int i = 0; i < 3; i++)
Assert.AreEqual(i * 2, wrapperList[i].Value);
var valueTypeWrapperList = new List<IntWrapperValueType>();
for (int i = 0; i < 3; i++)
valueTypeWrapperList.Add(new IntWrapperValueType() { Value = i });
vectors.IntWrapperValueTypeVector = valueTypeWrapperList;
valueTypeWrapperList = vectors.IntWrapperValueTypeVector;
for (int i = 0; i < 3; i++)
Assert.AreEqual(i, valueTypeWrapperList[i].Value);
} }
} }

11
tests/STL/STL.cpp

@ -1,5 +1,16 @@
#include "STL.h" #include "STL.h"
TestVectors::TestVectors()
{
IntVector.push_back(2);
IntVector.push_back(3);
IntVector.push_back(4);
IntPtrVector.push_back(&IntVector[0]);
IntPtrVector.push_back(&IntVector[1]);
IntPtrVector.push_back(&IntVector[2]);
}
std::vector<int> TestVectors::GetIntVector() std::vector<int> TestVectors::GetIntVector()
{ {
std::vector<int> vec; std::vector<int> vec;

1
tests/STL/STL.cs

@ -13,6 +13,7 @@ namespace CppSharp.Tests
public override void Preprocess(Driver driver, ASTContext ctx) public override void Preprocess(Driver driver, ASTContext ctx)
{ {
ctx.SetClassAsValueType("IntWrapperValueType");
} }
public static void Main(string[] args) public static void Main(string[] args)

22
tests/STL/STL.h

@ -1,10 +1,30 @@
#include "../Tests.h" #include "../Tests.h"
#include <vector> #include <vector>
struct DLL_API IntWrapper
{
int Value;
};
struct DLL_API IntWrapperValueType
{
int Value;
};
struct DLL_API TestVectors struct DLL_API TestVectors
{ {
TestVectors();
std::vector<int> GetIntVector(); std::vector<int> GetIntVector();
int SumIntVector(std::vector<int>& vec); int SumIntVector(std::vector<int>& vec);
// Should get mapped to List<int>
std::vector<int> IntVector; std::vector<int> IntVector;
// Should get mapped to List<IntPtr>
std::vector<int*> IntPtrVector;
// Should get mapped to List<IntWrapper>
std::vector<IntWrapper> IntWrapperVector;
// Should get mapped to List<IntWrapper>
std::vector<IntWrapper*> IntWrapperPtrVector;
// Should get mapped to List<IntWrapperValueType>
std::vector<IntWrapperValueType> IntWrapperValueTypeVector;
}; };

Loading…
Cancel
Save