3

can anyone explain why the code below fails?

type TIDEThemeObserverFunc = reference to procedure(foo: integer);
var fObserverFuncs: TList<TIDEThemeObserverFunc>

function RegisterEventObserver(aObserverFunc: TIDEThemeObserverFunc): Pointer;
begin
  fObserverFuncs.Add(aObserverFunc);
  Result := @aObserverFunc;

  // line below somehow fails
  assert(fObserverFuncs.IndexOf(TIDEThemeObserverFunc(Result)) <> -1);
end;

I assumed anonymous methods can simply be casted and used around via pointers but that seems like a wrong assumption. Also, any resources explaining how the anonymous methods are implemented under the hood would be great. TIA.

utku_karatas
  • 6,163
  • 4
  • 40
  • 52

2 Answers2

5

You should use PPointer(@aObserverFunc)^ instead of @aObserverFunc to avoid the failed assert.

@gabr: thanks for ref to my blog, but I should recommend first to read the Stackoverflow user Barry Kelly blog as a more competent source of information.

kludg
  • 27,213
  • 5
  • 67
  • 118
  • 2
    Reference counting for the list should work, as it is of type `TList<(some method reference type)>`. If reference counting broke with generics, even trivial cases like `TList` would be useless. – Barry Kelly Feb 22 '10 at 17:12
4

Anonymous methods are actually interfaces (more correct - objects implementing an interface).

Read more here: Anonymous methods in Delphi: the internals (written by Stackoverflow user Serg).

Community
  • 1
  • 1
gabr
  • 26,580
  • 9
  • 75
  • 141