AGB  ·  Datenschutz  ·  Impressum  







Anmelden
Nützliche Links
Registrieren
Zurück Delphi-PRAXiS Sprachen und Entwicklungsumgebungen Object-Pascal / Delphi-Language Delphi Beispiel für Attribut an einem Methoden/Funktionsparameter
Thema durchsuchen
Ansicht
Themen-Optionen

Beispiel für Attribut an einem Methoden/Funktionsparameter

Ein Thema von mjustin · begonnen am 2. Dez 2022 · letzter Beitrag vom 2. Dez 2022
Antwort Antwort
mjustin

Registriert seit: 14. Apr 2008
3.006 Beiträge
 
Delphi 2009 Professional
 
#1

Beispiel für Attribut an einem Methoden/Funktionsparameter

  Alt 2. Dez 2022, 11:17
Delphi-Version: 5
Der Thread "boolean function: muss result := false gesetzt werden?" brachte mich zu einer älteren Fragestellung zurück:

Is it possible to use Attributes on Delphi method arguments?

Die Antwort war Ja (es war nur undokumentiert) und in der Antwort auf Stackoverflow war auch ein Beispiel. Dieses zeigte: RTTI findet das Attribut der Methode.

Nun meine Zusatzfrage: wie kann ich den konkreten Wert des Parameters, also zum Aufrufzeitpunkt, ermitteln?

Ich vermutete zuerst, dass zum Beispiel in Spring4D etwas in dieser Richtung enthalten ist (leider nein). Ich denke, es wäre ein guter Eintrag für die Codebibliothek. Da ich nun gelegentlich auch in einer neueren Delphi-Version unterwegs bin, würde ich gerne diese kleine Aufgabe lösen:
  1. ein neues Attribut definieren: [NotNil]
  2. Parameter, die dieses Attribut enthalten, werden zur Laufzeit geprüft.
  3. Ist der übergebene Parameterwert nil, wird eine Exception ausgelöst.
Dazu suche ich nun Code, um per RTTI den konkreten Parameterwert auszulesen, also den Wert, der in dem attribuierten Parameter steht.

Beispiel für die Verwendung des Attributs:

Delphi-Quellcode:
procedure TMyClass.OnChangeMe([NotNil] ASender: TObject);
begin
  // hier ist ASender 'garantiert' nicht nil
  // ... mache etwas
end;
Michael Justin
habarisoft.com
  Mit Zitat antworten Zitat
Benutzerbild von himitsu
himitsu

Registriert seit: 11. Okt 2003
Ort: Elbflorenz
44.184 Beiträge
 
Delphi 12 Athens
 
#2

AW: Beispiel für Attribut an einem Methoden/Funktionsparameter

  Alt 2. Dez 2022, 12:06
Bei direktem Aufruf, ist ein gezieltes if Param=nil oder ein Assert(Assigned(Patem) garantiert einfacher und vor allem auch "optimaler".

Aber z.B. für Schnittstellen, wo Funktionsaufrufe weitergeleitet oder Events mit externen/ungeprüften Parameter aufgerufen werden ...
Nja, am Ende wäre auch das die direkte Prüfung einfacher, aber vermutlich in den Zwischenebenen das RTTI auch nutzbar.


Wenn der Methoden-Aufruf nicht via RTTI vorgenommen würde und du bereits Deklaration und die Parameter in RTTI-freundlicher Form vorliegen,
* mußt du erstmal die Definition der Methode selbst reingeben oder aus der Codeposition versuchen zu finden (bei Events hat du den Typ bereits in der Hand)
* und dann die Parameter auch noch bekommen
* * mitten im Code nahezu unmöglich ... aber beim / vor dem Aufruf oder als RTTI-Hook im Aufruf ging es aber

TRttiProcedureType/TRttiMethodType/TRttiMethod.Invoke oder mit dem TVirtualMethodInterceptor



In diesem Fall würde ich dir empfehlen, dieses [NotNil] bzw. ein [Check(...)] als FeatureRequst dem Hersteller zu unterbreiten
damit der Compiler automatisiert eine if Assigned einfügt, ähnlich wie bei [Weak] , [Volatile] und [Ref] oder den Index- und Überlaufprüfungen durch impliziten zusätzlichen Code.
$2B or not $2B

Geändert von himitsu ( 2. Dez 2022 um 12:14 Uhr)
  Mit Zitat antworten Zitat
Der schöne Günther

Registriert seit: 6. Mär 2013
6.176 Beiträge
 
Delphi 10 Seattle Enterprise
 
#3

AW: Beispiel für Attribut an einem Methoden/Funktionsparameter

  Alt 2. Dez 2022, 13:00
Ich wüsste jetzt nicht, wie man herausbekommt, in welcher Methode man aktuell grade steckt. Wenn man die TRttiMethod kennt, kann man sich da ja weiterhangeln.

Eine Möglichkeit wäre ein TVirtualMethodInterceptor der eine bestehende Instanz wrapped und vor/nach jedem Methodenaufruf z.B. die Parameter prüft, verändert, oder was auch immer. Setzt halt nur virtuelle Methoden vorraus und macht das ganze bestimmt nicht schneller als ein hartkodiertes if not Assigned(p) then raise EArgumentNilException .
  Mit Zitat antworten Zitat
Benutzerbild von himitsu
himitsu

Registriert seit: 11. Okt 2003
Ort: Elbflorenz
44.184 Beiträge
 
Delphi 12 Athens
 
#4

AW: Beispiel für Attribut an einem Methoden/Funktionsparameter

  Alt 2. Dez 2022, 13:17
Nja, im Prinzip in der Methode, welche kurz vor der aktuellen CodePosition beginnt, aber sicher ist sowas nicht.
Via RTTI alle Klassen+Methoden (nicht normale Prozeduren/Funktionen) durchlaufen und die Adressen vergleichen
oder über Debuginfos.

Ein __METHOD__, __FUNCTION__, __LINE__ bzw. eigene Preprozessor gibt es ja leider im "Delphi" nicht.
https://docwiki.embarcadero.com/RADS...inierte_Makros
$2B or not $2B

Geändert von himitsu ( 2. Dez 2022 um 13:19 Uhr)
  Mit Zitat antworten Zitat
mjustin

Registriert seit: 14. Apr 2008
3.006 Beiträge
 
Delphi 2009 Professional
 
#5

AW: Beispiel für Attribut an einem Methoden/Funktionsparameter

  Alt 2. Dez 2022, 13:20
Danke für das Feedback - ja, der TVirtualMethodInterceptor ist hier der Lösungsansatz, und ich stimme 100% zu dass ein Assert() auch funktioniert.

Im verlinkten Stackoverflow-Artikel war das Anwendungsbeispiel etwas fortgeschrittener, es sollte ein REST-Request-Parameter extrahiert werden. Durch die Annotation des Parameters mappt man dessen konkreten Wert auf den Anteil des Requests, in dem dieser enthalten ist. Das kann ein Path-, ein Query- oder ein Body-Parameter sein.
Dann könnte man Methodensignaturen dieser Art verwenden:
Delphi-Quellcode:
[GET]
function TMyResource.GetArtikelbestand([PathParam] ArtikelNr: string; [QueryParam] Farbe: string = ''): TArtikelbestandResponse;
begin
  // in ArtikelNr steht nun die aus dem HTTP Request extrahierte Artikelnummer, und in Farbe entsprechend die Artikelfarbe (optional).
end;
Das würde dann aus der URL z.B. /api/v1/artikel/12345?farbe=blau die Parameter ermitteln und an die Methode weitergeben. Auch hier wäre ein Intercept notwendig, diesmal ausserdem ein Verändern der Parameterwerte, nicht nur ein Lesen.
Michael Justin
habarisoft.com
  Mit Zitat antworten Zitat
Benutzerbild von himitsu
himitsu

Registriert seit: 11. Okt 2003
Ort: Elbflorenz
44.184 Beiträge
 
Delphi 12 Athens
 
#6

AW: Beispiel für Attribut an einem Methoden/Funktionsparameter

  Alt 2. Dez 2022, 13:38
Sowas ähnliches geh auch im DataSnap bzw. RADServer von Emba,
welcher ebenfalls eine REST-Schnittstelle bietet.

Dazu dann auch noch Dinge ala Benutzerverwaltung/Zugriffsbeschränlungen einzelner Klassen oder Methoden.



Wie gesagt, hier wird die Funktion am Ende auf etwas Anderes umgeleitet und über das Framework aufgerufen, wo man vor dem Aufruf dann auch solche Prüfungen machen kann ... vor der Funktion und nicht erst darin.



Beim TVirtualMethodInterceptor wird die TypInfo der Klasse geklont, in der abgeleiteten VMT mit den InterceptorCalls die virtuellen Methoden umgeleitet und dann in der Instanz der KlassenZeiger umgebogen.
Leider auch bei ALLEN Virtuellen und nicht nur die Gewollten (könnte man aber anschließend selber wieder an der VMT rumfummeln/zurückbiegen).

beim Aufruf:
Adressen, Register und Stack in TInvokeInfo kopieren
intern mehrmals rumreichen
und am Ende wieder alles in Register/Stack schreiben und der CALL auf die originle Adresse.
$2B or not $2B

Geändert von himitsu ( 2. Dez 2022 um 13:40 Uhr)
  Mit Zitat antworten Zitat
Antwort Antwort


Forumregeln

Es ist dir nicht erlaubt, neue Themen zu verfassen.
Es ist dir nicht erlaubt, auf Beiträge zu antworten.
Es ist dir nicht erlaubt, Anhänge hochzuladen.
Es ist dir nicht erlaubt, deine Beiträge zu bearbeiten.

BB-Code ist an.
Smileys sind an.
[IMG] Code ist an.
HTML-Code ist aus.
Trackbacks are an
Pingbacks are an
Refbacks are aus

Gehe zu:

Impressum · AGB · Datenschutz · Nach oben
Alle Zeitangaben in WEZ +1. Es ist jetzt 19:54 Uhr.
Powered by vBulletin® Copyright ©2000 - 2024, Jelsoft Enterprises Ltd.
LinkBacks Enabled by vBSEO © 2011, Crawlability, Inc.
Delphi-PRAXiS (c) 2002 - 2023 by Daniel R. Wolf, 2024 by Thomas Breitkreuz