public override bool VisitManagedArrayType(ManagedArrayType array, TypeQualifiers quals) { var support = Context.SupportBefore; var arrayId = CGenerator.GenId(string.Format("{0}_array", Context.ArgName)); support.WriteLine("MonoArray* {0} = (MonoArray*) {1};", arrayId, Context.ArgName); var arraySizeId = CGenerator.GenId(string.Format("{0}_array_size", Context.ArgName)); support.WriteLine("uintptr_t {0} = mono_array_length({1});", arraySizeId, arrayId); var typePrinter = CTypePrinter; typePrinter.PrintScopeKind = CppTypePrintScopeKind.Local; var arrayTypedefName = array.Typedef.Visit(typePrinter); typePrinter.PrintScopeKind = CppTypePrintScopeKind.Qualified; var arrayElementName = array.Array.Type.Visit(typePrinter); var elementSize = string.Format("sizeof({0})", arrayElementName); var nativeArrayId = CGenerator.GenId(string.Format("{0}_native_array", Context.ArgName)); support.WriteLine("{0} {1};", arrayTypedefName, nativeArrayId); support.WriteLine("{0}.array = g_array_sized_new(/*zero_terminated=*/FALSE," + " /*clear_=*/TRUE, {1}, {2});", nativeArrayId, elementSize, arraySizeId); var elementClassId = CGenerator.GenId(string.Format("{0}_element_class", Context.ArgName)); support.WriteLine("MonoClass* {0} = mono_class_get_element_class({1});", elementClassId, CMarshalNativeToManaged.GenerateArrayTypeLookup(array.Array.Type, support)); var elementSizeId = CGenerator.GenId(string.Format("{0}_array_element_size", Context.ArgName)); support.WriteLine("gint32 {0} = mono_class_array_element_size({1});", elementSizeId, elementClassId); var iteratorId = CGenerator.GenId("i"); support.WriteLine("for (int {0} = 0; {0} < {1}; {0}++)", iteratorId, arraySizeId); support.WriteStartBraceIndent(); var elementId = CGenerator.GenId(string.Format("{0}_array_element", Context.ArgName)); var isValueType = CMarshalNativeToManaged.IsValueType(array.Array.Type); support.WriteLine("{5} {0} = {4}mono_array_addr_with_size({1}, {2}, {3});", elementId, arrayId, elementSizeId, iteratorId, isValueType ? string.Empty : "*(MonoObject**)", isValueType ? "char*" : "MonoObject*"); var ctx = new MarshalContext(Context.Context) { ArgName = elementId, ReturnVarName = elementId, ReturnType = array.Array.QualifiedType }; var marshal = new CMarshalManagedToNative(ctx) { UnboxPrimitiveValues = false }; array.Array.QualifiedType.Visit(marshal); if (!string.IsNullOrWhiteSpace(marshal.Context.SupportBefore)) { support.Write(marshal.Context.SupportBefore.ToString()); } support.WriteLine("g_array_append_val({0}.array, {1});", nativeArrayId, marshal.Context.Return.ToString()); support.WriteCloseBraceIndent(); Context.Return.Write("{0}", nativeArrayId); return(false); }
public CMarshalManagedToNative(MarshalContext marshalContext) : base(marshalContext) { UnboxPrimitiveValues = true; }
public CMarshalNativeToManaged(MarshalContext marshalContext) : base(marshalContext) { PrimitiveValuesByValue = false; }
public override bool VisitManagedArrayType(ManagedArrayType array, TypeQualifiers quals) { var support = Context.SupportBefore; var contextId = CGenerator.GenId("mono_context"); var arrayId = CGenerator.GenId(string.Format("{0}_array", Context.ArgName)); var elementClassId = CGenerator.GenId(string.Format("{0}_element_class", Context.ArgName)); var managedArray = array.Array; var elementType = managedArray.Type; support.WriteLine("MonoClass* {0} = mono_class_get_element_class({1});", elementClassId, GenerateArrayTypeLookup(elementType, support)); support.WriteLine("MonoArray* {0} = mono_array_new({1}.domain, {2}, {3}.array->len);", arrayId, contextId, elementClassId, Context.ArgName); var iteratorId = CGenerator.GenId("i"); support.WriteLine("for (int {0} = 0; {0} < {1}.array->len; {0}++)", iteratorId, Context.ArgName); support.WriteStartBraceIndent(); var typePrinter = CTypePrinter; string elementTypeName = elementType.Visit(typePrinter); var elementId = CGenerator.GenId(string.Format("{0}_array_element", Context.ArgName)); support.WriteLine("{0} {1} = g_array_index({2}.array, {0}, {3});", elementTypeName, elementId, Context.ArgName, iteratorId); var ctx = new MarshalContext(Context.Context) { ArgName = elementId, }; var marshal = new CMarshalNativeToManaged(ctx) { PrimitiveValuesByValue = true }; elementType.Visit(marshal); if (!string.IsNullOrWhiteSpace(marshal.Context.SupportBefore)) { support.Write(marshal.Context.SupportBefore.ToString()); } var isValueType = IsValueType(elementType); if (isValueType) { support.WriteLine("mono_array_set({0}, {1}, {2}, {3});", arrayId, elementTypeName, iteratorId, marshal.Context.Return.ToString()); } else { support.WriteLine("mono_array_setref({0}, {1}, {2});", arrayId, iteratorId, marshal.Context.Return.ToString()); } support.WriteCloseBraceIndent(); Context.Return.Write("{0}", arrayId); return(true); }
public void GenerateMethodInvocation(Method method) { GenerateMethodGCHandleLookup(method); var paramsToMarshal = method.Parameters.Where(p => !p.IsImplicit); var numParamsToMarshal = paramsToMarshal.Count(); var argsId = "0"; if (numParamsToMarshal > 0) { argsId = GeneratedIdentifier("args"); WriteLine("void* {0}[{1}];", argsId, numParamsToMarshal); } var contexts = new List <MarshalContext>(); int paramIndex = 0; foreach (var param in paramsToMarshal) { var ctx = new MarshalContext(Context) { ArgName = param.Name, Parameter = param, ParameterIndex = paramIndex }; contexts.Add(ctx); var marshal = new CMarshalNativeToManaged(ctx); param.QualifiedType.Visit(marshal); if (!string.IsNullOrWhiteSpace(marshal.Context.SupportBefore)) { Write(marshal.Context.SupportBefore); } WriteLine("{0}[{1}] = {2};", argsId, paramIndex++, marshal.Context.Return.ToString()); } var exceptionId = GeneratedIdentifier("exception"); WriteLine("MonoObject* {0} = 0;", exceptionId); var resultId = GeneratedIdentifier("result"); WriteLine("MonoObject* {0};", resultId); var methodId = GeneratedIdentifier("method"); var instanceId = method.IsStatic ? "0" : GeneratedIdentifier("instance"); WriteLine("{0} = mono_runtime_invoke({1}, {2}, {3}, &{4});", resultId, methodId, instanceId, argsId, exceptionId); WriteLine("if ({0} != 0)", exceptionId); WriteStartBraceIndent(); var errorId = GeneratedIdentifier("error"); WriteLine("mono_m2n_error_t {0};", errorId); WriteLine("{0}.type = MONO_M2N_EXCEPTION_THROWN;", errorId); WriteLine("{0}.exception = (MonoException*) {1};", errorId, exceptionId); WriteLine("mono_m2n_error({0});", errorId); WriteCloseBraceIndent(); foreach (var marshalContext in contexts) { if (!string.IsNullOrWhiteSpace(marshalContext.SupportAfter)) { Write(marshalContext.SupportAfter); } } }