[fpc-pascal] Get TMethod from function reference

Sven Barth pascaldragon at googlemail.com
Mon Sep 19 11:17:13 CEST 2022


Hairy Pixels <genericptr at gmail.com> schrieb am So., 18. Sep. 2022, 02:50:

>
>
> > On Sep 17, 2022, at 10:57 PM, Sven Barth <pascaldragon at googlemail.com>
> wrote:
> >
> > === code begin ===
> >
> > type
> >   TProc = reference to procedure;
> >   TMyClass = class
> >     procedure DoThis;
> >   end;
> >
> >   TCapturer = class(TInterfacedObject, TProc)
> >     m: procedure of object;
> >     procedure Anonymous1;
> >
> >     procedure TProc.Invoke = Anonymous1;
> >   end;
> >
> > var
> >   p: TProc;
> >   c: TMyClass;
> >   capturer: TCapturer;
> >   capturer_keepalive: IUnknown;
> > begin
> >   capturer := TCapturer.Create;
> >   capturer_keepalive := capturer;
> >   c := TMyClass.Create;
> >   capturer.m := @c.DoThis;
> >   p := capturer as TProc;
> > end.
> >
> > === code end ===
>
> Well if p is effectively TCapturer then you COULD get back TMethod from m
> (procedure of object) but the compiler doesn’t have a method generated for
> this.
>

No, you can't, because if you have multiple such assignments inside one
function the capture object is shared and you'd have multiple fields where
you wouldn't know to which anonymous function is belongs:

=== code begin ===

Proc1 := @c.OnChange;
Proc2 := @c.OnClick;
Proc3 := @c2.OnChange;

=== code end ===

Will result in the following capture object:

=== code begin ===

type
  TCapturer = class(TInterfacedObject, TProc1, TProc2, TProc3)
    m1: TNotifyEvent;
    m2: TNotifyEvent;
    m3: TNotifyEvent;

    procedure Anonymous1(Sender :TObject); //will call m1
    procedure Anonymous2(Sender: TObject); // will call m2
    procedure Anonymous3(Sender: TObject); // will call m3
  end;

=== code end ===

Please note that you can't rely on the index as other converted anonymous
methods (maybe with the same signature) might be intermixed. So you won't
know which field is used by what method.

I read your announcement email again last night and saw that TProc could
> actually be subclassed which opens up the possibility to read the field (if
> it’s not intentionally hidden) or use the RTTI perhaps even. Is that
> possible? If the field “m" is hidden I would say that should be exposed for
> the purposes of subclassing .
>

When you subclass a function reference you can not assign any function to
it, but you really need to use a self written class type that you use as
instance.

Regards,
Sven

>
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.freepascal.org/pipermail/fpc-pascal/attachments/20220919/07669958/attachment-0001.htm>


More information about the fpc-pascal mailing list