Пример #1
0
        public void GenerateDelegateConverterImplementation(AST.Delegate type)
        {
            const string dName = "___del";

            Strata = ApiStrata.ABI;
            var typeRef    = TypeRef(type, false);
            var typeRefABI = TypeRef(type, true);

            Line($"HRESULT DW{type.ShortId}::AbiFunc({DeclParameters(type.GetABIParametersCpp(true))})");
            Block(() =>
            {
                Line($"auto {dName} = runtime_cast<DW{type.ShortId}>(__i_);");
                Line($"if (!{dName}) return E_FAIL;");
                Spacer();
                ABIWrapperParameterValidation(type);
                ABIWrappedCall(type, null, $"{dName}->Func");
            });
            Spacer();

            Strata = ApiStrata.Normal;
            Line("template<>");
            Line($"{TypeRef(type, false)} ABIUtil<{typeRef}>::FromABI(void* fptr, IObject* ctx)");
            //Line($"Delegate<{Signature(type, false)}> DW{type.ShortId}::Lookup({TypeRef(type)} fptr, IObject* ctx)");
            Block(() =>
            {
                Line(
                    $@"if (fptr == &DW{type.ShortId}::AbiFunc)
{{
    auto wrapper = runtime_cast<DW{type.ShortId}>(ctx);
    if (!wrapper) throw Exception(""Unexpected context type for delegate translation"");
    return wrapper->Func;
}}

return [fn = ({typeRefABI})fptr, cp = com_ptr<IObject>(ctx)]({DeclParameters(type.Parameters)})");

                if (!type.Return.IsVoid)
                {
                    Code("    -> {0} ", VariableType(type.Return, AST.VariableContext.Return));
                }

                Block(() =>
                {
                    CallToABIMethodBody(type.Rename("fn"), "cp.Get()");
                }, ";");
            });
            Spacer();

            Line("template<>");
            Line("ABIOf<{0}> ABIUtil<{0}>::ToABI(const {0}& x)", typeRef);
            Block(() =>
            {
                Line($"ABIOf<{typeRef}> x_abi;");
                Line($"x_abi.Fn = &DW{type.ShortId}::AbiFunc;");
                Line($"x_abi.Ctx = DW{type.ShortId}::GetWrapper(x);");
                Line("return x_abi;");
            });
        }
Пример #2
0
        public void DefineDelegate(AST.Delegate type, string name = null)
        {
            if (name == null)
            {
                name = type.Name;
            }

            Namespace(type.Namespace, false, () =>
            {
                WriteXmlDocumentation(type.XmlDoc);
                Line($"{(Strata == ApiStrata.ABI ? "internal" : "public")} delegate {TypeRef(type.Return)} {name}({DeclParameters(type.Parameters)});");
            });
        }
Пример #3
0
        public void GenerateDelegateConverterDeclaration(AST.Delegate type)
        {
            var name = "DW" + type.ShortId;

            Strata = ApiStrata.ABI;
            var dSig = Signature(type, false);

            Line(
                $@"class comid(""{type.Id}"") {name} : public ComObject<{name}, Object>, public ABI::DelegateWrapperBase<{name},
    {dSig}>
{{
public:");
            Indent++;
            Line($"DW{type.ShortId}(const Delegate<{dSig}>& d) : DBase(d) {{ }}");
            Line($"static Delegate<{dSig}> Lookup({TypeRef(type)} fptr, IObject* ctx);");
            Line($"static HRESULT __stdcall AbiFunc({DeclParameters(type.GetABIParametersCpp(true))});");
            Indent--;
            Line("};");
            Spacer();
        }
Пример #4
0
        public void DefineDelegateWrapper(AST.Delegate type)
        {
            Strata = ApiStrata.ABI;

            Line($"public class D{type.ShortId} : Gluon.D_Base");
            Block(() =>
            {
                var argstring = DeclParameters(type.GetABIParametersCs(true));

                Line(
                    $@"private NativeDel _abi;
internal static readonly NativeDel FnDel = new NativeDel(Fn);
public static readonly IntPtr FnPtr = Marshal.GetFunctionPointerForDelegate(FnDel);
internal delegate HResult NativeDel({argstring});");

                Line();
                if (TargetMono)
                {
                    Line("[AOT.MonoPInvokeCallback(typeof(NativeDel))]");
                }
                Line($"private static HResult Fn({argstring})");
                Block(() =>
                {
                    Strata = ApiStrata.Normal;

                    Line($"var del = ((GCHandle)Marshal.GetObjectForIUnknown(__i_)).Target as {TypeRef(type)};");
                    Line();
                    Line("try");
                    Block(() =>
                    {
                        WriteWrappedCall(true, "del", type.Return, null, type.Parameters.ToArray());
                    });
                    Line("catch (Exception e)");
                    Block(() =>
                    {
                        foreach (var arg in type.GetABIParametersCs(true).Where(a => a.IsOut))
                        {
                            Line($"{arg.Name} = default({TypeRef(arg, true)});");
                        }

                        Line("return GluonObject.ExceptionToHResult(e);");
                    });
                });

                Line(
                    @"private D{1}(IntPtr fn, IntPtr ctx) : base(ctx)
{{
    _abi = (NativeDel)Marshal.GetDelegateForFunctionPointer(fn, typeof(NativeDel));
}}

public static {0} Wrap(IntPtr fn, IntPtr ctx)
{{
    if (fn == IntPtr.Zero)
        return null;
    else if (fn == D{1}.FnPtr)
        return ((GCHandle)Marshal.GetObjectForIUnknown(ctx)).Target as {0};
    else
        return new D{1}(fn, ctx).Call;
}}

public static DelegateBlob Unwrap({0} x)
{{
    return x == null ? new DelegateBlob(IntPtr.Zero, IntPtr.Zero) :
        new DelegateBlob(FnPtr, Marshal.GetIUnknownForObject(GCHandle.Alloc(x)));
}}

public static DelegateBlob[] ToABI_Array({0}[] x)
{{
    if (x == null) return null;
    var r = new DelegateBlob[x.Length];
    for (int i = 0; i < x.Length; i++) r[i] = Unwrap(x[i]);
    return r;
}}

public static {0}[] FromABI_Array(DelegateBlob[] x)
{{
    if (x == null) return null;
    var r = new {0}[x.Length];

    for (int i = 0; i < x.Length; i++)
        r[i] = Wrap(x[i].Fn, x[i].Ctx);
    return r;
}}
", TypeRef(type), type.ShortId);

                Line($"private {TypeRef(type.Return)} Call({DeclParameters(type.Parameters)})");
                Block(() =>
                {
                    Strata = ApiStrata.Normal;
                    WriteWrappedCall(false, "(int)_abi", type.Return, new AST.Parameter()
                    {
                        Type = BasicTypes.IntPtr, Name = "_ctx"
                    }, type.Parameters.ToArray());
                    Strata = ApiStrata.ABI;
                });
            });
        }