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. 59
      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 @@ -277,18 +277,6 @@ namespace Cxxi.Generators.CLI
if (!@class.IsValueType)
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
// fields to the managed value subtypes.
foreach (var @base in @class.Bases)
@ -306,6 +294,18 @@ namespace Cxxi.Generators.CLI @@ -306,6 +294,18 @@ namespace Cxxi.Generators.CLI
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)

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

@ -541,34 +541,53 @@ namespace Cxxi.Generators.CLI @@ -541,34 +541,53 @@ namespace Cxxi.Generators.CLI
@class.QualifiedOriginalName);
SupportBefore.PushIndent();
foreach (var field in @class.Fields)
{
var fieldRef = string.Format("{0}.{1}", Context.Parameter.Name,
field.Name);
MarshalValueClassFields(@class, marshalVar);
var marshalCtx = new MarshalContext(Context.Driver)
{
ArgName = fieldRef,
ParameterIndex = Context.ParameterIndex++
};
Return.Write(marshalVar);
var marshal = new CLIMarshalManagedToNativePrinter(TypeMapDatabase,
marshalCtx);
field.Visit(marshal);
if (Context.Parameter.Type.IsPointer())
ArgumentPrefix.Write("&");
}
Context.ParameterIndex = marshalCtx.ParameterIndex;
private void MarshalValueClassFields(Class @class, string marshalVar)
{
foreach (var @base in @class.Bases)
{
if (!@base.IsClass || @base.Class.Ignore)
continue;
if (!string.IsNullOrWhiteSpace(marshal.SupportBefore))
SupportBefore.WriteLine(marshal.SupportBefore);
var baseClass = @base.Class;
MarshalValueClassFields(baseClass, marshalVar);
}
SupportBefore.WriteLine("{0}.{1} = {2};", marshalVar, field.OriginalName,
marshal.Return);
foreach (var field in @class.Fields)
{
MarshalValueClassField(field, marshalVar);
}
}
Return.Write(marshalVar);
private void MarshalValueClassField(Field field, string marshalVar)
{
var fieldRef = string.Format("{0}.{1}", Context.Parameter.Name,
field.Name);
if (Context.Parameter.Type.IsPointer())
ArgumentPrefix.Write("&");
var marshalCtx = new MarshalContext(Context.Driver)
{
ArgName = fieldRef,
ParameterIndex = Context.ParameterIndex++
};
var marshal = new CLIMarshalManagedToNativePrinter(TypeMapDatabase,
marshalCtx);
field.Visit(marshal);
Context.ParameterIndex = marshalCtx.ParameterIndex;
if (!string.IsNullOrWhiteSpace(marshal.SupportBefore))
SupportBefore.WriteLine(marshal.SupportBefore);
SupportBefore.WriteLine("{0}.{1} = {2};", marshalVar, field.OriginalName,
marshal.Return);
}
public bool VisitFieldDecl(Field field)

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

@ -384,9 +384,23 @@ namespace Cxxi.Generators.CLI @@ -384,9 +384,23 @@ namespace Cxxi.Generators.CLI
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)
{
if (field.Ignore) continue;
if (CheckIgnoreField(@class, field)) continue;
var nativeField = string.Format("{0}->{1}",
nativePointer, field.OriginalName);
@ -465,11 +479,71 @@ namespace Cxxi.Generators.CLI @@ -465,11 +479,71 @@ namespace Cxxi.Generators.CLI
{
if (method.Kind != CXXMethodKind.Constructor)
GenerateFunctionCall(method, @class);
else
GenerateValueTypeConstructorCall(method, @class);
}
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)
{
if (function.Ignore)

Loading…
Cancel
Save