Autor Téma: Rozdil meli Object.Property:IInterface a GetInterfaceProp()  (Přečteno 190 krát)

Offline pf1957

  • Padawan
  • ******
  • Příspěvků: 2482
  • Karma: 131
    • Verze Delphi: D2007, XE3, DX10
Tak nejak tomu Delphi prestavam rozumet :'(

1. Mam sadu interfacu IXxxMessage, jejich taxonomie vypada takto: IInterface -> IBasalMessage -> IXxxMessage, instance za IXxxMessage jsou polymorfni tj. na urovni predka existuje virtualni metoda, kterou implementace IXxxMessage prekryvaji.
2. Mam model, ktery ma radu published properties s interface na ruzne zpravy tj.
Kód: Delphi [Vybrat]
  1.   property Xxx1: IXxx1Message read ....
  2.   property Xxx2: IXxx1Message read ....
  3.   property Xxx3: IXxx1Message read ....
  4.   ...
3. Mam metodu, ktera s temi zpravami neco dela a jeji signatura vypada takto:
Kód: Delphi [Vybrat]
  1. procedure A(AMessage:IBasalMessage);
4. Kdyz tu proceduru zavolam takto:
Kód: Delphi [Vybrat]
  1. A(model.Xxx1);
tak vsechno funguje jak ma.
5. Kdyz chci pouzit introspekci nejak takto:
Kód: Delphi [Vybrat]
  1.   ii := GetInterfaceProp(model, propertyName);
  2.   if Assigned(ii) and Supports(ii, IBasalMessage) then
  3.     A(ii as IBasalMessage);
Tak to nefunguje resp. funguji jen odkazy na members IBasalMessage, ale reference na members, ktere jsou clenem potomka IXxxMessage konci na AV (u 1. clenu na offsetu za poslednim memberem u IBasalMessage)

Nevi nekdo, co delam spatne?



Offline Delfin

  • Padawan
  • ******
  • Příspěvků: 1721
  • Karma: 66
  • SW konzultant
    • Verze Delphi: 2009, Tokyo
Re:Rozdil meli Object.Property:IInterface a GetInterfaceProp()
« Odpověď #1 kdy: 21-03-2019, 17:27:10 »
Mohli bychom MCVE? Nejak si ten problem nemuzu dat dohromady...
I'm a soldier, so don't panic! I know the underground! I like WTFPL license! No more Google, go duck, go!

Offline pf1957

  • Padawan
  • ******
  • Příspěvků: 2482
  • Karma: 131
    • Verze Delphi: D2007, XE3, DX10
Re:Rozdil meli Object.Property:IInterface a GetInterfaceProp()
« Odpověď #2 kdy: 21-03-2019, 17:45:43 »
Mohli bychom MCVE? Nejak si ten problem nemuzu dat dohromady...
Zacina jaro, prace na hospodarstvi volaji a o weekendu ma byt slusne pocasi, takze uvidim, jak budu po vecerech orvanej, prece jenom jsem uz starej cur*k, sedici cele dny nad klabosnici a kdyz mam byt cely den na nohou, tak jsem pak na umreni...

Momentalne jsem se vyhnul introspekci, protoze mam v tomto pripade shodou okolnosti k dispozici indexed property, takze jsem s temi interfejsy schopen pracovat pres enum. Ale protoze mam vsechno postavene na interfejsech, tak je mozne, ze se podobny problem vynori o kus vedle a budu ji potrebovat. Pak bych holt SSCCE udelal.



Ale princip je jednoduchy: polymorfismus, kteremu kdyz predhodim interface odkazem objekt.property, tak funguje. A kdyz zkusim hodnotu property ziskat volanim GetInterfaceProc(objekt, jmeno), tak ne.

Offline Delfin

  • Padawan
  • ******
  • Příspěvků: 1721
  • Karma: 66
  • SW konzultant
    • Verze Delphi: 2009, Tokyo
Re:Rozdil meli Object.Property:IInterface a GetInterfaceProp()
« Odpověď #3 kdy: 21-03-2019, 17:56:17 »
Ja vyrobil tohle, ale nedokazu rict jak moc je to mimo od realne situace; vim, nejsou tam prekryvane metody, ale mel jsem za to, ze se problem tyka ziskani interface za pomoci RTTI (Tokyo s timto nema problem):

Kód: Delphi [Vybrat]
  1. uses
  2.   TypInfo;
  3.  
  4. type
  5.   IBaseMessage = interface
  6.   ['{9159B5CD-1067-496F-BDE0-5031188A563F}']
  7.     procedure DoSomethingBase;
  8.   end;
  9.  
  10.   ISpecificMessage = interface(IBaseMessage)
  11.   ['{763B6C53-EE41-4AAB-9B7B-7DA758D64137}']
  12.     procedure DoSomethingSpecific;
  13.   end;
  14.  
  15.   TSpecificMessage = class(TInterfacedObject, IBaseMessage, ISpecificMessage)
  16.   public
  17.     { IBaseMessage }
  18.     procedure DoSomethingBase;
  19.     { ISpecificMessage }
  20.     procedure DoSomethingSpecific;
  21.   end;
  22.  
  23.   TMyModel = class
  24.   private
  25.     FTheMessage: ISpecificMessage;
  26.   published
  27.     property TheMessage: ISpecificMessage read FTheMessage write FTheMessage;
  28.   end;
  29.  
  30. implementation
  31.  
  32. procedure A(AMessage: IBaseMessage);
  33. begin
  34.   AMessage.DoSomethingBase;
  35. end;
  36.  
  37. { TSpecificMessage }
  38.  
  39. procedure TSpecificMessage.DoSomethingBase;
  40. begin
  41.   ShowMessage('DoSomethingBase');
  42. end;
  43.  
  44. procedure TSpecificMessage.DoSomethingSpecific;
  45. begin
  46.   ShowMessage('DoSomethingSpecific');
  47. end;
  48.  
  49. procedure TForm1.FormCreate(Sender: TObject);
  50. var
  51.   Model: TMyModel;
  52.   Payload: IInterface;
  53. begin
  54.   Model := TMyModel.Create;
  55.   try
  56.     Model.TheMessage := TSpecificMessage.Create;
  57.  
  58.     Payload := GetInterfaceProp(Model, 'TheMessage');
  59.     if Assigned(Payload) and Supports(Payload, IBaseMessage) then
  60.       A(Payload as IBaseMessage);
  61.   finally
  62.     Model.Free;
  63.   end;
  64. end;
« Poslední změna: 21-03-2019, 18:05:53 od Delfin »
I'm a soldier, so don't panic! I know the underground! I like WTFPL license! No more Google, go duck, go!

Offline pf1957

  • Padawan
  • ******
  • Příspěvků: 2482
  • Karma: 131
    • Verze Delphi: D2007, XE3, DX10
Re:Rozdil meli Object.Property:IInterface a GetInterfaceProp()
« Odpověď #4 kdy: 21-03-2019, 18:17:33 »
Ja vyrobil tohle, ale nedokazu rict jak moc je to mimo od realne situace; vim, nejsou tam prekryvane metody, ale mel jsem za to, ze se problem tyka ziskani interface za pomoci RTTI (Tokyo s timto nema problem):
Uz to dneska balim. Aby se to vice podobalo, tak by DoSomethingBase melo byt virtualni a u specificke message prekryto a a v nem sahat po member variables, ktere v base class nejsou.
Pri tom mi to pada na AV.