Esempio n. 1
0
        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;
            }
        }
Esempio n. 2
0
        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);");
            });
        }
Esempio n. 3
0
        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);
        }