Browse Source

Improved wide char handling in the C# and CLI.

References #320.
pull/356/head
triton 11 years ago
parent
commit
6bd26ac443
  1. 29
      src/Generator/Generators/CLI/CLIMarshal.cs
  2. 5
      src/Generator/Generators/CLI/CLITypePrinter.cs
  3. 23
      src/Generator/Generators/CSharp/CSharpMarshal.cs
  4. 3
      src/Generator/Generators/CSharp/CSharpTypePrinter.cs
  5. 2
      src/Generator/Types/CppTypePrinter.cs
  6. 9
      tests/Basic/Basic.Tests.cs
  7. 8
      tests/Basic/Basic.h

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

@ -3,6 +3,7 @@ using System.Linq;
using System.Text; using System.Text;
using CppSharp.AST; using CppSharp.AST;
using CppSharp.AST.Extensions; using CppSharp.AST.Extensions;
using CppSharp.Generators.CSharp;
using CppSharp.Types; using CppSharp.Types;
using Delegate = CppSharp.AST.Delegate; using Delegate = CppSharp.AST.Delegate;
using Type = CppSharp.AST.Type; using Type = CppSharp.AST.Type;
@ -73,10 +74,10 @@ namespace CppSharp.Generators.CLI
return true; return true;
} }
if (pointee.IsPrimitiveType(PrimitiveType.Char)) if (CSharpTypePrinter.IsConstCharString(pointer))
{ {
Context.Return.Write("clix::marshalString<clix::E_UTF8>({0})", Context.Return.Write(MarshalStringToManaged(Context.ReturnVarName,
Context.ReturnVarName); pointer.Pointee.Desugar() as BuiltinType));
return true; return true;
} }
@ -95,11 +96,12 @@ namespace CppSharp.Generators.CLI
if (quals.IsConst != Context.ReturnType.Qualifiers.IsConst) if (quals.IsConst != Context.ReturnType.Qualifiers.IsConst)
{ {
var nativeTypePrinter = new CppTypePrinter(Context.Driver.TypeDatabase, false); var nativeTypePrinter = new CppTypePrinter(Context.Driver.TypeDatabase, false);
var returnType = Context.ReturnType.Type.Desugar();
var constlessPointer = new PointerType() var constlessPointer = new PointerType()
{ {
IsDependent = pointer.IsDependent, IsDependent = pointer.IsDependent,
Modifier = pointer.Modifier, Modifier = pointer.Modifier,
QualifiedPointee = new QualifiedType(Context.ReturnType.Type.GetPointee()) QualifiedPointee = new QualifiedType(returnType.GetPointee())
}; };
var nativeConstlessTypeName = constlessPointer.Visit(nativeTypePrinter, new TypeQualifiers()); var nativeConstlessTypeName = constlessPointer.Visit(nativeTypePrinter, new TypeQualifiers());
returnVarName = string.Format("const_cast<{0}>({1})", returnVarName = string.Format("const_cast<{0}>({1})",
@ -138,6 +140,25 @@ namespace CppSharp.Generators.CLI
return pointer.Pointee.Visit(this, quals); return pointer.Pointee.Visit(this, quals);
} }
private string MarshalStringToManaged(string varName, BuiltinType type)
{
var encoding = type.Type == PrimitiveType.Char ?
Encoding.ASCII : Encoding.Unicode;
if (Equals(encoding, Encoding.ASCII))
encoding = Context.Driver.Options.Encoding;
if (Equals(encoding, Encoding.ASCII))
return string.Format("clix::marshalString<clix::E_UTF8>({0})", varName);
if (Equals(encoding, Encoding.Unicode) ||
Equals(encoding, Encoding.BigEndianUnicode))
return string.Format("clix::marshalString<clix::E_UTF16>({0})", varName);
throw new NotSupportedException(string.Format("{0} is not supported yet.",
Context.Driver.Options.Encoding.EncodingName));
}
public override bool VisitMemberPointerType(MemberPointerType member, public override bool VisitMemberPointerType(MemberPointerType member,
TypeQualifiers quals) TypeQualifiers quals)
{ {

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

@ -2,6 +2,7 @@
using System.Collections.Generic; using System.Collections.Generic;
using CppSharp.AST; using CppSharp.AST;
using CppSharp.AST.Extensions; using CppSharp.AST.Extensions;
using CppSharp.Generators.CSharp;
using CppSharp.Types; using CppSharp.Types;
using Type = CppSharp.AST.Type; using Type = CppSharp.AST.Type;
@ -139,10 +140,8 @@ namespace CppSharp.Generators.CLI
return string.Format("{0}^", function.Visit(this, quals)); return string.Format("{0}^", function.Visit(this, quals));
} }
if (pointee.IsPrimitiveType(PrimitiveType.Char) && quals.IsConst) if (CSharpTypePrinter.IsConstCharString(pointer))
{
return "System::String^"; return "System::String^";
}
// From http://msdn.microsoft.com/en-us/library/y31yhkeb.aspx // From http://msdn.microsoft.com/en-us/library/y31yhkeb.aspx
// Any of the following types may be a pointer type: // Any of the following types may be a pointer type:

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

@ -146,7 +146,8 @@ namespace CppSharp.Generators.CSharp
if (CSharpTypePrinter.IsConstCharString(pointer)) if (CSharpTypePrinter.IsConstCharString(pointer))
{ {
Context.Return.Write(MarshalStringToManaged(Context.ReturnVarName)); Context.Return.Write(MarshalStringToManaged(Context.ReturnVarName,
pointer.Pointee.Desugar() as BuiltinType));
return true; return true;
} }
@ -167,17 +168,21 @@ namespace CppSharp.Generators.CSharp
return pointer.Pointee.Visit(this, quals); return pointer.Pointee.Visit(this, quals);
} }
private string MarshalStringToManaged(string varName) private string MarshalStringToManaged(string varName, BuiltinType type)
{ {
if (Equals(Context.Driver.Options.Encoding, Encoding.ASCII)) var encoding = type.Type == PrimitiveType.Char ?
{ Encoding.ASCII : Encoding.Unicode;
if (Equals(encoding, Encoding.ASCII))
encoding = Context.Driver.Options.Encoding;
if (Equals(encoding, Encoding.ASCII))
return string.Format("Marshal.PtrToStringAnsi({0})", varName); return string.Format("Marshal.PtrToStringAnsi({0})", varName);
}
if (Equals(Context.Driver.Options.Encoding, Encoding.Unicode) || if (Equals(encoding, Encoding.Unicode) ||
Equals(Context.Driver.Options.Encoding, Encoding.BigEndianUnicode)) Equals(encoding, Encoding.BigEndianUnicode))
{
return string.Format("Marshal.PtrToStringUni({0})", varName); return string.Format("Marshal.PtrToStringUni({0})", varName);
}
throw new NotSupportedException(string.Format("{0} is not supported yet.", throw new NotSupportedException(string.Format("{0} is not supported yet.",
Context.Driver.Options.Encoding.EncodingName)); Context.Driver.Options.Encoding.EncodingName));
} }

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

@ -176,8 +176,9 @@ namespace CppSharp.Generators.CSharp
var pointee = pointer.Pointee.Desugar(); var pointee = pointer.Pointee.Desugar();
return (pointee.IsPrimitiveType(PrimitiveType.Char) || return (pointee.IsPrimitiveType(PrimitiveType.Char) ||
pointee.IsPrimitiveType(PrimitiveType.Char16) ||
pointee.IsPrimitiveType(PrimitiveType.WideChar)) && pointee.IsPrimitiveType(PrimitiveType.WideChar)) &&
pointer.QualifiedPointee.Qualifiers.IsConst; pointer.QualifiedPointee.Qualifiers.IsConst;
} }
public static bool IsConstCharString(QualifiedType qualType) public static bool IsConstCharString(QualifiedType qualType)

2
src/Generator/Types/CppTypePrinter.cs

@ -103,7 +103,7 @@ namespace CppSharp.Types
case PrimitiveType.Bool: return "bool"; case PrimitiveType.Bool: return "bool";
case PrimitiveType.Void: return "void"; case PrimitiveType.Void: return "void";
case PrimitiveType.Char16: case PrimitiveType.Char16:
case PrimitiveType.WideChar: return "char"; case PrimitiveType.WideChar: return "wchar_t";
case PrimitiveType.Char: return "char"; case PrimitiveType.Char: return "char";
case PrimitiveType.UChar: return "unsigned char"; case PrimitiveType.UChar: return "unsigned char";
case PrimitiveType.Short: return "short"; case PrimitiveType.Short: return "short";

9
tests/Basic/Basic.Tests.cs

@ -369,6 +369,7 @@ public class BasicTests : GeneratorTestFixture
Assert.That(prop.FieldValue, Is.EqualTo(10)); Assert.That(prop.FieldValue, Is.EqualTo(10));
} }
[Test]
public void TestVariable() public void TestVariable()
{ {
// Test field property // Test field property
@ -377,6 +378,14 @@ public class BasicTests : GeneratorTestFixture
Assert.That(TestVariables.VALUE, Is.EqualTo(10)); Assert.That(TestVariables.VALUE, Is.EqualTo(10));
} }
[Test]
public void TestWideStrings()
{
var ws = new TestWideStrings();
var s = ws.WidePointer;
Assert.That(ws.WidePointer, Is.EqualTo("Hello"));
}
[Test] [Test]
public unsafe void TestArraysPointers() public unsafe void TestArraysPointers()
{ {

8
tests/Basic/Basic.h

@ -508,6 +508,14 @@ struct DLL_API TestVariables
int TestVariables::VALUE; int TestVariables::VALUE;
void TestVariables::SetValue(int value) { VALUE = value; } void TestVariables::SetValue(int value) { VALUE = value; }
typedef const wchar_t * LPCWSTR;
struct DLL_API TestWideStrings
{
LPCWSTR GetWidePointer();
};
LPCWSTR TestWideStrings::GetWidePointer() { return L"Hello"; }
enum struct MyEnum { A, B, C }; enum struct MyEnum { A, B, C };
class DLL_API TestArraysPointers class DLL_API TestArraysPointers

Loading…
Cancel
Save