Browse Source

Added improved support for C# marshaling of types.

pull/1/head
triton 12 years ago
parent
commit
3912d4a5d9
  1. 64
      src/Generator/Generators/CSharp/CSharpMarshal.cs
  2. 3
      src/Generator/Generators/CSharp/CSharpTypePrinter.cs

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

@ -3,14 +3,23 @@ using Cxxi.Types;
namespace Cxxi.Generators.CSharp namespace Cxxi.Generators.CSharp
{ {
public enum CSharpMarshalKind
{
Unknown,
NativeField
}
public class CSharpMarshalContext : MarshalContext public class CSharpMarshalContext : MarshalContext
{ {
public CSharpMarshalContext(Driver driver) public CSharpMarshalContext(Driver driver)
: base(driver) : base(driver)
{ {
Kind = CSharpMarshalKind.Unknown;
Cleanup = new TextGenerator(); Cleanup = new TextGenerator();
} }
public CSharpMarshalKind Kind { get; set; }
public TextGenerator Cleanup { get; private set; } public TextGenerator Cleanup { get; private set; }
} }
@ -69,13 +78,13 @@ namespace Cxxi.Generators.CSharp
if (pointee.Desugar().IsPrimitiveType(PrimitiveType.Void)) if (pointee.Desugar().IsPrimitiveType(PrimitiveType.Void))
{ {
Context.Return.Write("new IntPtr({0})", Context.ReturnVarName); Context.Return.Write("new System.IntPtr({0})", Context.ReturnVarName);
return true; return true;
} }
if (pointee.IsPrimitiveType(PrimitiveType.Char)) if (CSharpTypePrinter.IsConstCharString(pointer))
{ {
Context.Return.Write("Marshal.StringToHGlobalAnsi({0})", Context.Return.Write("Marshal.PtrToStringAnsi(new System.IntPtr({0}))",
Context.ReturnVarName); Context.ReturnVarName);
return true; return true;
} }
@ -83,7 +92,7 @@ namespace Cxxi.Generators.CSharp
PrimitiveType primitive; PrimitiveType primitive;
if (pointee.Desugar().IsPrimitiveType(out primitive)) if (pointee.Desugar().IsPrimitiveType(out primitive))
{ {
Context.Return.Write("new IntPtr({0})", Context.ReturnVarName); Context.Return.Write("new System.IntPtr({0})", Context.ReturnVarName);
return true; return true;
} }
@ -145,7 +154,7 @@ namespace Cxxi.Generators.CSharp
FunctionType function; FunctionType function;
if (decl.Type.IsPointerTo(out function)) if (decl.Type.IsPointerTo(out function))
{ {
Context.SupportBefore.WriteLine("var {0} = new IntPtr({1});", Context.SupportBefore.WriteLine("var {0} = new System.IntPtr({1});",
Helpers.GeneratedIdentifier("ptr"), Context.ReturnVarName); Helpers.GeneratedIdentifier("ptr"), Context.ReturnVarName);
Context.Return.Write("({1})Marshal.GetDelegateForFunctionPointer({0}, typeof({1}))", Context.Return.Write("({1})Marshal.GetDelegateForFunctionPointer({0}, typeof({1}))",
@ -172,14 +181,21 @@ namespace Cxxi.Generators.CSharp
public override bool VisitClassDecl(Class @class) public override bool VisitClassDecl(Class @class)
{ {
var instance = string.Empty; var ctx = Context as CSharpMarshalContext;
string instance = Context.ReturnVarName;
if (ctx.Kind == CSharpMarshalKind.NativeField)
{
if (Context.ReturnVarName.StartsWith("*"))
Context.ReturnVarName = Context.ReturnVarName.Substring(1);
if (!Context.ReturnType.IsPointer()) instance = string.Format("new System.IntPtr({0})",
instance += "&"; Context.ReturnVarName);
}
instance += Context.ReturnVarName; Context.Return.Write("new {0}({1})", QualifiedIdentifier(@class),
instance);
WriteClassInstance(@class, instance);
return true; return true;
} }
@ -191,12 +207,6 @@ namespace Cxxi.Generators.CSharp
return string.Format("{0}", decl.QualifiedName); return string.Format("{0}", decl.QualifiedName);
} }
public void WriteClassInstance(Class @class, string instance)
{
Context.Return.Write("new {0}({1})", QualifiedIdentifier(@class),
instance);
}
public override bool VisitFieldDecl(Field field) public override bool VisitFieldDecl(Field field)
{ {
return field.Type.Visit(this); return field.Type.Visit(this);
@ -247,11 +257,13 @@ namespace Cxxi.Generators.CSharp
// native side, we need to be careful and protect it with an // native side, we need to be careful and protect it with an
// explicit GCHandle if necessary. // explicit GCHandle if necessary.
var sb = new StringBuilder(); //var sb = new StringBuilder();
sb.AppendFormat("({0})(", type); //sb.AppendFormat("({0})(", type);
sb.Append("Marshal.GetFunctionPointerForDelegate("); //sb.Append("Marshal.GetFunctionPointerForDelegate(");
sb.AppendFormat("{0}).ToPointer())", Context.Parameter.Name); //sb.AppendFormat("{0}).ToPointer())", Context.Parameter.Name);
Context.Return.Write(sb.ToString()); //Context.Return.Write(sb.ToString());
Context.Return.Write(Context.Parameter.Name);
return true; return true;
} }
@ -296,7 +308,8 @@ namespace Cxxi.Generators.CSharp
Context.Return.Write("{0}.Instance", Context.Return.Write("{0}.Instance",
Helpers.SafeIdentifier(Context.Parameter.Name)); Helpers.SafeIdentifier(Context.Parameter.Name));
else else
Context.Return.Write("new IntPtr(&{0})", Context.Parameter.Name); Context.Return.Write("new System.IntPtr(&{0})",
Context.Parameter.Name);
return true; return true;
} }
@ -517,6 +530,13 @@ namespace Cxxi.Generators.CSharp
} }
else else
{ {
if (parameter.Kind == ParameterKind.OperatorParameter)
{
Context.Return.Write("new System.IntPtr(&{0})",
parameter.Name);
return true;
}
Context.Return.Write("*({0}.Internal*)&{1}", Context.Return.Write("*({0}.Internal*)&{1}",
@class.Name, parameter.Name); @class.Name, parameter.Name);
return true; return true;

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

@ -7,7 +7,8 @@ namespace Cxxi.Generators.CSharp
public enum CSharpTypePrinterContextKind public enum CSharpTypePrinterContextKind
{ {
Native, Native,
Managed Managed,
ManagedPointer
} }
public class CSharpTypePrinterContext : TypePrinterContext public class CSharpTypePrinterContext : TypePrinterContext

Loading…
Cancel
Save