Browse Source

Merge pull request #60 from ddobrev/master

Added support for Unicode when marshalling strings
pull/61/merge
João Matos 12 years ago
parent
commit
bc4e28b238
  1. 7
      src/Generator/Driver.cs
  2. 38
      src/Generator/Generators/CSharp/CSharpMarshal.cs
  3. 9
      tests/Basic/Basic.Tests.cs
  4. 5
      tests/Basic/Basic.cpp
  5. 2
      tests/Basic/Basic.h
  6. 15
      tests/UTF16/UTF16.Tests.cs
  7. 1
      tests/UTF16/UTF16.cpp
  8. 33
      tests/UTF16/UTF16.cs
  9. 13
      tests/UTF16/UTF16.h
  10. 2
      tests/UTF16/premake4.lua

7
src/Generator/Driver.cs

@ -1,4 +1,5 @@
using CppSharp.AST; using System.Text;
using CppSharp.AST;
using CppSharp.Generators; using CppSharp.Generators;
using CppSharp.Generators.CLI; using CppSharp.Generators.CLI;
using CppSharp.Generators.CSharp; using CppSharp.Generators.CSharp;
@ -226,6 +227,8 @@ namespace CppSharp
OutputInteropIncludes = true; OutputInteropIncludes = true;
MaxIndent = 80; MaxIndent = 80;
CommentPrefix = "///"; CommentPrefix = "///";
Encoding = Encoding.ASCII;
} }
// General options // General options
@ -274,6 +277,8 @@ namespace CppSharp
public int MaxIndent; public int MaxIndent;
public string CommentPrefix; public string CommentPrefix;
public Encoding Encoding { get; set; }
private string inlinesLibraryName; private string inlinesLibraryName;
public string InlinesLibraryName public string InlinesLibraryName
{ {

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

@ -1,6 +1,7 @@
using System; using System;
using System.Collections.Generic; using System.Collections.Generic;
using System.Linq; using System.Linq;
using System.Text;
using CppSharp.AST; using CppSharp.AST;
using CppSharp.Types; using CppSharp.Types;
using Type = CppSharp.AST.Type; using Type = CppSharp.AST.Type;
@ -133,8 +134,7 @@ namespace CppSharp.Generators.CSharp
if (CSharpTypePrinter.IsConstCharString(pointer)) if (CSharpTypePrinter.IsConstCharString(pointer))
{ {
Context.Return.Write("Marshal.PtrToStringAnsi({0})", Context.Return.Write(MarshalStringToManaged(Context.ReturnVarName));
Context.ReturnVarName);
return true; return true;
} }
@ -151,6 +151,21 @@ namespace CppSharp.Generators.CSharp
return true; return true;
} }
private string MarshalStringToManaged(string varName)
{
if (Equals(Context.Driver.Options.Encoding, Encoding.ASCII))
{
return string.Format("Marshal.PtrToStringAnsi({0})", varName);
}
if (Equals(Context.Driver.Options.Encoding, Encoding.Unicode) ||
Equals(Context.Driver.Options.Encoding, Encoding.BigEndianUnicode))
{
return string.Format("Marshal.PtrToStringUni({0})", varName);
}
throw new NotSupportedException(string.Format("{0} is not supported yet.",
Context.Driver.Options.Encoding.EncodingName));
}
public override bool VisitPrimitiveType(PrimitiveType primitive, TypeQualifiers quals) public override bool VisitPrimitiveType(PrimitiveType primitive, TypeQualifiers quals)
{ {
switch (primitive) switch (primitive)
@ -359,8 +374,8 @@ namespace CppSharp.Generators.CSharp
type.IsPrimitiveType(PrimitiveType.WideChar)) && type.IsPrimitiveType(PrimitiveType.WideChar)) &&
pointer.QualifiedPointee.Qualifiers.IsConst) pointer.QualifiedPointee.Qualifiers.IsConst)
{ {
Context.Return.Write("Marshal.StringToHGlobalAnsi({0})", Context.Return.Write(this.MarshalStringToUnmanaged(
Helpers.SafeIdentifier(Context.Parameter.Name)); Helpers.SafeIdentifier(Context.Parameter.Name)));
CSharpContext.Cleanup.WriteLine("Marshal.FreeHGlobal({0});", CSharpContext.Cleanup.WriteLine("Marshal.FreeHGlobal({0});",
Helpers.SafeIdentifier(Context.ArgName)); Helpers.SafeIdentifier(Context.ArgName));
return true; return true;
@ -402,6 +417,21 @@ namespace CppSharp.Generators.CSharp
return pointee.Visit(this, quals); return pointee.Visit(this, quals);
} }
private string MarshalStringToUnmanaged(string varName)
{
if (Equals(Context.Driver.Options.Encoding, Encoding.ASCII))
{
return string.Format("Marshal.StringToHGlobalAnsi({0})", varName);
}
if (Equals(Context.Driver.Options.Encoding, Encoding.Unicode) ||
Equals(Context.Driver.Options.Encoding, Encoding.BigEndianUnicode))
{
return string.Format("Marshal.StringToHGlobalUni({0})", varName);
}
throw new NotSupportedException(string.Format("{0} is not supported yet.",
Context.Driver.Options.Encoding.EncodingName));
}
public override bool VisitPrimitiveType(PrimitiveType primitive, TypeQualifiers quals) public override bool VisitPrimitiveType(PrimitiveType primitive, TypeQualifiers quals)
{ {
switch (primitive) switch (primitive)

9
tests/Basic/Basic.Tests.cs

@ -1,4 +1,4 @@
using System.Reflection; using System.Reflection;
using NUnit.Framework; using NUnit.Framework;
using Basic; using Basic;
@ -103,5 +103,12 @@ public class BasicTests
Assert.That(typeof(Foo2).GetProperty("P", Assert.That(typeof(Foo2).GetProperty("P",
BindingFlags.Instance | BindingFlags.NonPublic), Is.Not.Null); BindingFlags.Instance | BindingFlags.NonPublic), Is.Not.Null);
} }
[Test]
public void TestANSI()
{
Foo foo = new Foo();
Assert.That(foo.GetANSI(), Is.EqualTo("ANSI"));
}
} }

5
tests/Basic/Basic.cpp

@ -4,6 +4,11 @@ Foo::Foo()
{ {
} }
const char* Foo::GetANSI()
{
return "ANSI";
}
Foo2 Foo2::operator<<(signed int i) Foo2 Foo2::operator<<(signed int i)
{ {
Foo2 foo; Foo2 foo;

2
tests/Basic/Basic.h

@ -11,6 +11,8 @@ public:
Foo(); Foo();
int A; int A;
float B; float B;
const char* GetANSI();
}; };
class DLL_API Foo2 : public Foo class DLL_API Foo2 : public Foo

15
tests/UTF16/UTF16.Tests.cs

@ -0,0 +1,15 @@
using NUnit.Framework;
using UTF16;
[TestFixture]
public class UTF16Tests
{
[Test]
public void TestFoo()
{
var foo = new Foo();
const string georgia = "საქართველო";
foo.Unicode = georgia;
Assert.That(foo.Unicode, Is.EqualTo(georgia));
}
}

1
tests/UTF16/UTF16.cpp

@ -0,0 +1 @@
#include "UTF16.h"

33
tests/UTF16/UTF16.cs

@ -0,0 +1,33 @@
using System.Text;
using CppSharp.AST;
using CppSharp.Generators;
using CppSharp.Utils;
namespace CppSharp.Tests
{
public class UTF16Tests : LibraryTest
{
public UTF16Tests(LanguageGeneratorKind kind)
: base("UTF16", kind)
{
}
public override void SetupPasses(Driver driver)
{
driver.Options.Encoding = Encoding.Unicode;
}
public override void Preprocess(Driver driver, Library lib)
{
}
static class Program
{
public static void Main(string[] args)
{
ConsoleDriver.Run(new UTF16Tests(LanguageGeneratorKind.CSharp));
}
}
}
}

13
tests/UTF16/UTF16.h

@ -0,0 +1,13 @@
#if defined(_MSC_VER)
#define DLL_API __declspec(dllexport)
#else
#define DLL_API
#endif
class DLL_API Foo
{
public:
const char* Unicode;
};
DLL_API int FooCallFoo(Foo* foo);

2
tests/UTF16/premake4.lua

@ -0,0 +1,2 @@
group "Tests/UTF16"
SetupTestCSharp("UTF16")
Loading…
Cancel
Save