Salut à tous :) il est ma première question à stackoverflow :)Est-il possible de créer une instance TRttiMethod pour TRttiType avec TypeKind = tkMethod?
dans Delphi XE2 RTTI nous avons la classe TRttiMethod et il a une fonction CreateImplementation()
Wich permet de créer de façon dynamique la procédure ou la fonction avec la même signature et une méthode anonimous comme corps. En utilisant TRttiContext.getMethods()
/getMethod()
on peut obtenir la collection de méthodes de classe - collection de TRttiMethod. La documentation indique (http://docwiki.embarcadero.com/VCL/en/RTTI.TRttiMethod) de ne pas créer directement TRTTiMethod et d'utiliser getMethods() pour obtenir ses instances. Donc, si nous avons l'instance TRTTIMethod
, nous pouvons créer dynamiquement une méthode avec la même signature et l'invoquer plus tard.
la question est .. par exemple, nous avons TNotifyEvent ... TRttiContext.getType(typeinfo(TNotifyEvent))
retours TRttiType
exemple wich objet a TypeKind = tkMethod
. nous savons que la signature de TNotifyEvent est la procédure (expéditeur: TObject) de l'objet;
est-il possible d'obtenir TRttiMethod
pour cela? Je souhaite créer dynamiquement eventHandler pour l'événement en utilisant TRttiMethod.CreateImplementation()
ou peut-être existe-t-il un autre moyen de créer dynamiquement une implémentation de méthode? PS: l'idée est de créer quelque chose comme une chaîne d'événements. Au moment de la compilation, nous ne connaissons pas le type/la signature de l'événement, donc nous pouvons utiliser des génériques pour cela, comme TEvenChain <TNotifyEvent>. La chaîne a une collection sur les gestionnaires d'événements enregistrés, donc parce que nous ne connaissons pas le type de gestionnaire au moment de la compilation, nous devons le créer dynamiquement, et ce gestionnaire obtient seulement ses paramètres et appelle le gestionnaire enregistré avec eux.
mise à jour: ici est un code (idée est de créer la chaîne de gestionnaires d'événements):
procedure TMainForm.FormCreate(Sender: TObject);
begin
FEventChain := TNotifyChain.Create();
FEventChain.AddHandler(event1);
FEventChain.AddHandler(event2);
TestButton.OnClick := FEventChain.EventHandler;
end;
Event1
& event2
sont des méthodes (sender : TObject)
de la forme; ce n'est pas exemple générique (T dans ce cas est NotifyEvent/Tchain <TNotifyEvent>) TEventChain.EventHandler
est TNotifyEvent
trop
TNotifyChain
est
TNotifyChain = class(TObject)
strict private
FEvent : TNotifyEvent;
FItems : TList<TNotifyEvent>;
FCtx : TRttiContext;
public
procedure TestNotifyHandler(sender : TObject); virtual; abstract;
constructor Create();
procedure AddHandler(eh : TNotifyEvent);
property EventHandler : TNotifyEvent read FEvent;
end;
EventHandler
propriété est mappée à la variable FEvent
. Et FEvent
n'est pas affecté car nous supposons que le type d'événement/gestionnaire est inconnu.
donc dans le constructeur, nous créons la méthode virtuelle avec la signature TNotifyEvent
et assignez son code à FEvent
:
constructor TNotifyChain.Create();
var st: TRttiType;
//et : TRttiMethodType;
Callback : TMethodImplementationCallback;
rttiMethod : TRttiMethod;
m : TMethod;
mi : TMethodImplementation;
begin
inherited;
FItems := TList<TNotifyEvent>.Create();
FCtx := TRttiContext.Create();
//et := FCtx.GetType(typeinfo(TNotifyEvent)) as TRttiMethodType;
st := FCtx.GetType(self.ClassType);
rttiMethod := st.GetMethod('TestNotifyHandler');
Callback := procedure(UserData: Pointer;
const Args: TArray<TValue>;
out Result: TValue)
var i : integer;
e : TMethod;
begin
for i := 0 to FItems.Count - 1 do begin
e := TMethod(Fitems[i]);
result := Invoke(e.Code, args, rttiMethod.CallingConvention, nil);
end;
end;
mi := rttiMethod.CreateImplementation(self, Callback);
m.data := self;
m.Code := mi.CodeAddress;
FEvent := TNotifyEvent(m);
end;
J'utilise ici TestNotifyHandler
méthode pour créer gestionnaire réel avec la même signature en utilisant TRttimethod.CreateImplementation()
Je suppose que oui , il existe un moyen de créer l'implémentation du gestionnaire d'événements au moment de l'exécution en utilisant TRttiMethodType
de TNotifyEvent
car il contient des informations sur les paramètres type/count et la convention d'appel de l'événement réel utilisé (dans le cas générique).
Jusqu'où êtes-vous arrivé maintenant? – menjaraz
@menjaraz Je n'ai pas résolu ce problème. Ce n'était pas une "vraie" tâche pour moi, "juste pour m'amuser". J'ai écrit un article à ce sujet dans mon blog: http://teran.karelia.pro/articles/item_4508.html (mais il est à l'origine en russe); vous pouvez utiliser Google pour traduire en anglais [link] http://translate.google.com/translate?sl=ru&tl=fr&js=n&prev=_t&hl=ru&ie=UTF-8&layout=2&eotf=1&u=http%3A%2F% 2Fteran.karelia.pro% 2Farticles% 2Fitem_4508.html & act = url – teran
Merci d'avoir répondu. – menjaraz