Bonjour,
J'ai eu un souci que je voudrais partager avec vous mon retour d'experience. Je m'explique :
J'ai implémenté un EventMulticast avec Delphi et je me suis heurté à un problème.
comment connaitre la classe de l'objet implementant une interface
quand on a seulement une référence de cette interface?
Exemple: Test est du type ITest;
Ma première idée était de déclarer une interface IImplementeurProvider comme suit
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3 if Test is TEventMulticaster then (...)
GetImplementeur se contente de renvoyer Self.
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4 IImplementorProvider = interface [GUID] function GetImplementeur: TObject; end;
en faisant dériver ITest de IImplementeurProvider on a
Cette technique fonctionne bien.
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3 if Test.GetImplementeur is TEventMulticaster then (...)
et puis je suis tombé sur cet article
http://hallvards.blogspot.com/2004/0...in-delphi.html
Je reporte le code ici au cas où le lien décéderais.
j'ai juste eu besoin de remplacer PChar par PAnsiChar pour que ca fonctionne.
résultat plus besoin du IImplementeurProvider
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34 function GetImplementingObject(const I: IInterface): TObject; const AddByte = $04244483; AddLong = $04244481; type PAdjustSelfThunk = ^TAdjustSelfThunk; TAdjustSelfThunk = packed record case AddInstruction: longint of AddByte : (AdjustmentByte: shortint); AddLong : (AdjustmentLong: longint); end; PInterfaceMT = ^TInterfaceMT; TInterfaceMT = packed record QueryInterfaceThunk: PAdjustSelfThunk; end; TInterfaceRef = ^PInterfaceMT; var QueryInterfaceThunk: PAdjustSelfThunk; begin Result := Pointer(I); if Assigned(Result) then try QueryInterfaceThunk := TInterfaceRef(I)^.QueryInterfaceThunk; case QueryInterfaceThunk.AddInstruction of AddByte: Inc(PChar(Result), QueryInterfaceThunk.AdjustmentByte); AddLong: Inc(PChar(Result), QueryInterfaceThunk.AdjustmentLong); else Result := nil; end; except Result := nil; end; end;
Comme le signal un commentaire de l'article, ceci n'est pas au principe de l'objet. mais bon ça m'a aidé et aidera peut être d'autres aussi.
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3 if GetImplementingObject(Test) is TEventMulticaster then (...)
voilà.
Partager