public void MethodImplementation(AST.ICallSignature m, AST.Type type, Action implementation = null) { if (Strata == ApiStrata.Normal) { UseLocalTranslations = false; Code("{0} {1}::{2}(", VariableType(m.Return), TypeRef(type), m.Name); UseLocalTranslations = true; Code(DeclParameters(m.Parameters)); if (m.IsConst) { Line(") const"); } else { Line(")"); } Block(() => { if (implementation != null) { implementation(); } else if (Settings.Mode == CppMode.PimplWrapper) { CallToABIMethodBody(m.Rename("_abi->_" + m.GetComCompatibleName())); } else { PlaceholderMethodBody(m); } }); } else { var args = m.Parameters; Line("HRESULT {0}::_{1}({2})", TypeRef(type.ToVariable(), false), m.GetComCompatibleName(), DeclParameters(m.GetABIParametersCpp())); Strata = ApiStrata.Normal; Block(() => { if (implementation == null) { CallFromABIMethodBody(m); } else { implementation(); } }); Strata = ApiStrata.ABI; } }
public void WriteArrayMemberConverter(AST.Type type) { var tn = TypeRef(type, false); var tnabi = TypeRef(type, true); if (type.IsDelegate) { tnabi = "DelegateBlob"; } Line("public static {0}[] FromABI{1}(IntPtr data, int count)", tn, type.ShortId); Block(() => { Line("if(data == IntPtr.Zero) return null;"); Line("var sz = Marshal.SizeOf<{0}>();", tnabi); Line("var r = new {0}[count];", tn); Line("for(int i = 0;i < count;i++)"); Block(() => { if (type.IsStruct) { if (CsRender.RequiresABITranslation(type.ToVariable())) { Line("r[i] = {0}.FromABI(Marshal.PtrToStructure<{0}>((IntPtr)((long)data + i * sz)));", tnabi); } else { Line("r[i] = Marshal.PtrToStructure<{0}>((IntPtr)((long)data + i * sz));", tnabi); } } else if (type.IsDelegate) { Line("var blob = Marshal.PtrToStructure<{0}>((IntPtr)((long)data + i * sz));", tnabi); Line("r[i] = D{0}.Wrap(blob.Fn, blob.Ctx);", type.ShortId); } else if (type.IsObject) { Line("r[i] = GluonObject.Of<{0}>(Marshal.ReadIntPtr((IntPtr)((long)data + i * sz)));", tn); } else { throw new InvalidOperationException("This writer only designed to write for structs, delegates, and classes"); } }); Line("Marshal.FreeCoTaskMem(data);"); Line("return r;"); }); Line("public static ArrayBlob ToABI{1}({0}[] arr)", tn, type.ShortId); Block(() => { Line("if(arr == null) return new ArrayBlob();"); Line("var sz = Marshal.SizeOf<{0}>();", tnabi); Line("var r = new ArrayBlob(Marshal.AllocCoTaskMem(sz * arr.Length), arr.Length);"); Line("for(int i = 0;i < arr.Length;i++)"); Block(() => { if (type.IsStruct) { if (CsRender.RequiresABITranslation(type.ToVariable())) { Line("Marshal.StructureToPtr({0}.ToABI(arr[i]), r.Ptr + sz * i, false);", tnabi); } else { Line("Marshal.StructureToPtr(arr[i], r.Ptr + sz * i, false);", tnabi); } } else if (type.IsDelegate) { Line("var blob = D{0}.Unwrap(arr[i]);", type.ShortId); Line("Marshal.StructureToPtr(blob, (IntPtr)((long)r.Ptr + sz * i), false);"); } else if (type.IsObject) { Line("var item = arr[i];"); Line("Marshal.WriteIntPtr((IntPtr)((long)r.Ptr + sz * i), item == null ? IntPtr.Zero : item.IPtr);"); } }); Line("return r;"); }); Line("public static void FreeABI{0}(IntPtr data, int count)", type.ShortId); Block(() => { Line("Marshal.FreeCoTaskMem(data);"); }); }
public override string TypeName(AST.Type t, bool?abi = null) { var useabi = RequiresABITranslation(t.ToVariable()) && (abi ?? Strata == ApiStrata.ABI); if (t.IsVoid) { return("void"); } if (t == BasicTypes.IUnknown) { t = BasicTypes.IntPtr; } if (useabi && (/*v.IsArray ||*/ t.IsObject)) { return("IntPtr"); } var qn = t.Name; if (t.IsDelegate) { var d = (AST.Delegate)t; if (useabi) { return("IntPtr"); } else if (d.IsGeneric) { CsRender writer = new CsRender(); if (!d.Return.IsVoid) { writer.Code("Func<"); writer.BeginList(CodeListStyle.Compact); foreach (var arg in d.Parameters) { writer.ListItem(TypeName(arg, false)); } writer.ListItem(TypeName(d.Return)); writer.EndList(); writer.Code(">"); } else if (d.Parameters.Count == 0) { return("Action"); } else { writer.Code("Action<"); writer.BeginList(CodeListStyle.Compact); foreach (var arg in d.Parameters) { writer.ListItem(TypeName(arg, false)); } writer.EndList(); writer.Code(">"); } return(writer.ToString()); } } if ((t.IsObject || t.IsDelegate || t.IsStruct) && (WorkingABINamespace != useabi || WorkingNamespace != t.Namespace)) { if (useabi) { if (t.IsObject || t.IsDelegate) { return("IntPtr"); } else { return("ABI." + t.FullName(".")); } } else { return("global::" + t.FullName(".")); } } if (t.IsEnum && WorkingABINamespace) { return("global::" + t.FullName(".")); } return(ScopeTo(t.Namespace) + qn); }