Browse Source

Merge pull request #4 from esdrubal/master

Value type marshaling improvements
pull/1/head
João Matos 13 years ago
parent
commit
8d0bebcdea
  1. 24
      src/Generator/Generators/CLI/CLIHeadersTemplate.cs
  2. 31
      src/Generator/Generators/CLI/CLIMarshal.cs
  3. 76
      src/Generator/Generators/CLI/CLISourcesTemplate.cs

24
src/Generator/Generators/CLI/CLIHeadersTemplate.cs

@ -277,18 +277,6 @@ namespace Cxxi.Generators.CLI
if (!@class.IsValueType) if (!@class.IsValueType)
return; return;
PushIndent();
foreach (var field in @class.Fields)
{
if (CheckIgnoreField(@class, field)) continue;
GenerateDeclarationCommon(field);
if (@class.IsUnion)
WriteLine("[FieldOffset({0})]", field.Offset);
WriteLine("{0} {1};", field.Type, SafeIdentifier(field.Name));
}
PopIndent();
// Handle the case of struct (value-type) inheritance by adding the base // Handle the case of struct (value-type) inheritance by adding the base
// fields to the managed value subtypes. // fields to the managed value subtypes.
foreach (var @base in @class.Bases) foreach (var @base in @class.Bases)
@ -306,6 +294,18 @@ namespace Cxxi.Generators.CLI
GenerateClassFields(baseClass); GenerateClassFields(baseClass);
} }
PushIndent();
foreach (var field in @class.Fields)
{
if (CheckIgnoreField(@class, field)) continue;
GenerateDeclarationCommon(field);
if (@class.IsUnion)
WriteLine("[FieldOffset({0})]", field.Offset);
WriteLine("{0} {1};", field.Type, SafeIdentifier(field.Name));
}
PopIndent();
} }
public void GenerateClassEvents(Class @class) public void GenerateClassEvents(Class @class)

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

@ -541,7 +541,32 @@ namespace Cxxi.Generators.CLI
@class.QualifiedOriginalName); @class.QualifiedOriginalName);
SupportBefore.PushIndent(); SupportBefore.PushIndent();
MarshalValueClassFields(@class, marshalVar);
Return.Write(marshalVar);
if (Context.Parameter.Type.IsPointer())
ArgumentPrefix.Write("&");
}
private void MarshalValueClassFields(Class @class, string marshalVar)
{
foreach (var @base in @class.Bases)
{
if (!@base.IsClass || @base.Class.Ignore)
continue;
var baseClass = @base.Class;
MarshalValueClassFields(baseClass, marshalVar);
}
foreach (var field in @class.Fields) foreach (var field in @class.Fields)
{
MarshalValueClassField(field, marshalVar);
}
}
private void MarshalValueClassField(Field field, string marshalVar)
{ {
var fieldRef = string.Format("{0}.{1}", Context.Parameter.Name, var fieldRef = string.Format("{0}.{1}", Context.Parameter.Name,
field.Name); field.Name);
@ -565,12 +590,6 @@ namespace Cxxi.Generators.CLI
marshal.Return); marshal.Return);
} }
Return.Write(marshalVar);
if (Context.Parameter.Type.IsPointer())
ArgumentPrefix.Write("&");
}
public bool VisitFieldDecl(Field field) public bool VisitFieldDecl(Field field)
{ {
Context.Parameter = new Parameter Context.Parameter = new Parameter

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

@ -384,9 +384,23 @@ namespace Cxxi.Generators.CLI
private void GenerateStructMarshaling(Class @class, string nativePointer) private void GenerateStructMarshaling(Class @class, string nativePointer)
{ {
GenerateStructMarshalingFields(@class, nativePointer);
}
private void GenerateStructMarshalingFields(Class @class, string nativePointer)
{
foreach (var @base in @class.Bases)
{
if (!@base.IsClass || @base.Class.Ignore)
continue;
var baseClass = @base.Class;
GenerateStructMarshalingFields(baseClass, nativePointer);
}
foreach (var field in @class.Fields) foreach (var field in @class.Fields)
{ {
if (field.Ignore) continue; if (CheckIgnoreField(@class, field)) continue;
var nativeField = string.Format("{0}->{1}", var nativeField = string.Format("{0}->{1}",
nativePointer, field.OriginalName); nativePointer, field.OriginalName);
@ -465,11 +479,71 @@ namespace Cxxi.Generators.CLI
{ {
if (method.Kind != CXXMethodKind.Constructor) if (method.Kind != CXXMethodKind.Constructor)
GenerateFunctionCall(method, @class); GenerateFunctionCall(method, @class);
else
GenerateValueTypeConstructorCall(method, @class);
} }
WriteCloseBraceIndent(); WriteCloseBraceIndent();
} }
private void GenerateValueTypeConstructorCall(Method method, Class @class)
{
var names = new List<string>();
foreach (var param in method.Parameters)
{
var ctx = new MarshalContext(Driver)
{
Parameter = param,
ArgName = param.Name,
};
var marshal = new CLIMarshalManagedToNativePrinter(Driver.TypeDatabase,
ctx);
param.Visit(marshal);
if (!string.IsNullOrWhiteSpace(marshal.SupportBefore))
WriteLine(marshal.SupportBefore);
names.Add(marshal.Return);
}
WriteLine("auto _native = ::{0}({1});", @class.QualifiedOriginalName,
string.Join(", ", names));
GenerateValueTypeConstructorCallFields(@class);
}
private void GenerateValueTypeConstructorCallFields(Class @class)
{
foreach (var @base in @class.Bases)
{
if (!@base.IsClass || @base.Class.Ignore)
continue;
var baseClass = @base.Class;
GenerateValueTypeConstructorCallFields(baseClass);
}
foreach (var field in @class.Fields)
{
if (CheckIgnoreField(@class, field)) continue;
var varName = string.Format("_native.{0}", field.OriginalName);
var ctx = new MarshalContext(Driver)
{
ReturnVarName = varName,
ReturnType = field.Type
};
var marshal = new CLIMarshalNativeToManagedPrinter(Driver, ctx);
field.Visit(marshal);
WriteLine("this->{0} = {1};", field.Name, marshal.Return);
}
}
public void GenerateFunction(Function function, Namespace @namespace) public void GenerateFunction(Function function, Namespace @namespace)
{ {
if (function.Ignore) if (function.Ignore)

Loading…
Cancel
Save