Black Friday = Pricewatch Bekijk onze selectie van de beste Black Friday-deals en voorkom een miskoop.

[Delphi] method call via adres (pointer)

Pagina: 1
Acties:

  • wizl
  • Registratie: Maart 2001
  • Laatst online: 27-02-2023
Ik heb de volgende interface:

code:
1
2
3
4
5
6
7
8
  IObserver = interface
    procedure Notify;
  end;

  type
  TFoo = class(TInterfacedObject, IObserver)
    procedure Notify;
  end;


Als ik op deze manier Notify aanroep werkt het:
code:
1
2
Foo := TFoo.Create;
IObserver(Foo).Notify;


Als ik het op de volgende manier doe, krijg ik access violations ;(
code:
1
IObserver(Pointer(Foo)).Notify;


Kan iemand wat licht op de zaak schijnen voor mij?

  • Icelus
  • Registratie: Januari 2004
  • Niet online
De ‘Pointer(Foo)’ maakt van Foo een normale pointer. Type-casting naar IObserver is niet mogelijk omdat niet bekend is naar welke implementatie de interface van IObserver moet ‘wijzen’.

[ Voor 80% gewijzigd door Icelus op 07-07-2008 16:46 ]

Developer Accused Of Unreadable Code Refuses To Comment


  • wizl
  • Registratie: Maart 2001
  • Laatst online: 27-02-2023
De Notify-implementatie van Foo lijkt me?

Verwijderd

wizl schreef op maandag 07 juli 2008 @ 16:53:
De Notify-implementatie van Foo lijkt me?
Die is niet bekend in een normale pointer. Een pointer is niets dan een adres van een geheugenplek. Dat adres, niets anders dan een getal, weet niets van types laat staan welke interface ondersteund wordt door een object waar dat getal naar wijst. Waarom zou je trouwens pointers willen gebruiken? Waarom niet variabelen van het type IObserver gebruiken? Dat is het hele idee van interfaces.

  • wizl
  • Registratie: Maart 2001
  • Laatst online: 27-02-2023
Misschien moet ik dan wat meer code posten. Ik wil een willekeurig object (TInterfacedObject, IStateObserver) registeren als observer dat doe ik met behulp van:

code:
1
2
3
4
5
6
7
procedure TWorkflowHandler.RegisterObserver(FStateObserver: IStateObserver);
begin
  if not Assigned(FStateObservers) then FStateObservers := TList.Create;

  if FStateObservers.IndexOf(Pointer(FStateObserver)) = -1 then
    FStateObservers.Add(Pointer(FStateObserver));
end;


Vervolgens wil ik alle geregistreerde observers een Notify sturen (als dat nodig is)
code:
1
2
3
4
5
6
7
8
procedure TWorkflowHandler.NotifyObservers;
var
  i: integer ;
begin
  for  i := 0 to FStateObservers.Count - 1 do begin
    IStateObserver(FStateObservers[i]).Notify;
  end;
end;

Verwijderd

TInterfaceList?

Eerst casten naar TObject en dan met as of met een directe cast de interface eruit halen kan ook, maar TInterfaceList is denk ik wat je zoekt.

  • LordLarry
  • Registratie: Juli 2001
  • Niet online

LordLarry

Aut disce aut discede

Met interfaces kan je niet op die manier casten. Dat gaat via IUnknown.QueryInterface. Of de Support functie of met as.

We adore chaos because we like to restore order - M.C. Escher


  • wizl
  • Registratie: Maart 2001
  • Laatst online: 27-02-2023
Verwijderd schreef op dinsdag 08 juli 2008 @ 00:17:
TInterfaceList?

Eerst casten naar TObject en dan met as of met een directe cast de interface eruit halen kan ook, maar TInterfaceList is denk ik wat je zoekt.
Als ik i.p.v. TList een TInterfaceList gebruik dan werkt het _/-\o_
Pagina: 1