AGB  ·  Datenschutz  ·  Impressum  







Anmelden
Nützliche Links
Registrieren
Thema durchsuchen
Ansicht
Themen-Optionen

Routine mit Namen aufrufen

Ein Thema von Sigi55 · begonnen am 20. Feb 2015 · letzter Beitrag vom 25. Feb 2015
Antwort Antwort
Seite 1 von 2  1 2      
Benutzerbild von himitsu
himitsu

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

AW: Routine mit Namen aufrufen

  Alt 20. Feb 2015, 21:52
Delphi-Quellcode:
procedure TForm1.Hello_World(Sender: TObject);

TExecute = procedure of object;
Und schon hat jemand Mist gebaut, denn die Signaturen stimmen nicht überein.

Zum Glück liegt dieser Parameter zufällig in den Registern und nicht auf'm Stack,
so steht da nur Schrott drin und es knallt nicht gleich.
Ein Therapeut entspricht 1024 Gigapeut.

Geändert von himitsu (20. Feb 2015 um 21:54 Uhr)
  Mit Zitat antworten Zitat
Sigi55

Registriert seit: 3. Jan 2010
36 Beiträge
 
Delphi 5 Professional
 
#2

AW: Routine mit Namen aufrufen

  Alt 21. Feb 2015, 06:21
Moin erstmal,

also, wozu braucht er das ?

Ich hab mir so eine Art Taskplaner, unix-cron, etc.. geschrieben.
Die jobs lese ich aus einer DB-Tabelle und arbeite sie zeitgesteuert ab.
Der "JobName" ist die Bezeichnung der aufzurufen Procedure den ich per Variable
übergebe.

Das klappt auch alles wunderbar, nur liegen nicht alle Proceduren auf der
Hauptform ...

z.Z. mache ich es über den Umweg

Delphi-Quellcode:
procedure TForm1.Button1Click(Sender: TObject);
begin
  ExecuteRoutine(Form1, Datensicherung);
end;

procedure TForm1.Datensicherung(Sender: TObject);
begin
  DatenSicherungStarten;
end;
... und ich hätte gern etwas inder Art:

ExecuteRoutine(Unit??? oder wo auch immer, Datensicherung);
Das muss zwar alles nicht sein, ist auch kein Akt wenn es so nicht
zu machen ist, wäre nur schöner

Gruß

Sigi
  Mit Zitat antworten Zitat
hanvas

Registriert seit: 28. Okt 2010
171 Beiträge
 
Delphi 11 Alexandria
 
#3

AW: Routine mit Namen aufrufen

  Alt 21. Feb 2015, 08:55
Moin erstmal,

Ich hab mir so eine Art Taskplaner, unix-cron, etc.. geschrieben.
Die jobs lese ich aus einer DB-Tabelle und arbeite sie zeitgesteuert ab.
Der "JobName" ist die Bezeichnung der aufzurufen Procedure den ich per Variable
übergebe.

Sigi
Wenn ich das richtig verstehen dann gibt es keine "unbekannten" Prozeduren und Methoden sondern lediglich Objekte/Klassen die sich auf mehrere Units verteilen und die Du einheitlich aufrufen willst, Du weisst aber wo (in welcher Unit/Klasse) diese Funktionen ursprünglich definiert sind. Da du alle Methoden in Deinem Beispiel ohne Parameter aufrufen wolltest gehe ich davon aus das alle aufzurufenden Methoden paramterlos sind.

In jedem Fall würde ich dafür sorgen das sich die aufzurufenden Objekte/Methoden selbst bei einer zentralen Instanz "registrieren".

Delphi-Quellcode:
  

unit register;

....

type TJobRegister = class(TObject)
     private
       FRegister : TStringList;
     public
       procedure registerCall (const registeredName : String; m : pMethod);
       procedure Call(const registeredName : String);
     end;

function RegisteredJobs : TJobRegister; // singleton für arme

implementation

procedure TJobRegister.registerCall (const registeredName : String; m : pMethod);
begin
 if (FRegister.IndexOf(registeredName)<0) then
     FRegister.AddObject(registeredName,m);
end;

procedure TJobRegister.Call(const registeredName : String);
var idx : Integer;
begin
 idx := FRegister.IndexOf(registeredName);
 if (idx >= 0 ) then begin
                         TExecute(FRegister.Objects[idx]^).Execute;
                     end
                else begin
                       .....
                     end;
end;
Die Klassen deren Methoden aufgerufen werden sollen müssten dann die Unit Register verwenden und sich dort anmelden, beispielsweise so

Delphi-Quellcode:
  

uses Register;

type TUseable = class(TObject)
     public
      constructor Create;
      procedure TuWas;
     end;

constructor TUseable.Create;
var m : pMethod;
begin
 New(m);
 m.Data := self;
 m.Code := @TuWas;
 register.registeredJobs.registerCall('Irgendwas',m);
end;
Das hätte auch den Vorteil das Du beliebige Namen verwenden kannst. Die Registerklasse müsste sich freilich noch um die Freigabe der pMethod Variablen kümmern, eine Deregistrierung wäre angeraten wenn es passieren kann das Instanzen während der Laufzeit des Programmes zerstört werden etc. Aber wenn Du das so machst, dann kannst Du es auch gleich richtig machen und entweder Interfaces verwenden oder Dir einen Wrapper je aufzurufender Klasse schreiben und dessen Instanzen / Objekte registrieren.

cu Ha-Jö
  Mit Zitat antworten Zitat
Sigi55

Registriert seit: 3. Jan 2010
36 Beiträge
 
Delphi 5 Professional
 
#4

AW: Routine mit Namen aufrufen

  Alt 21. Feb 2015, 09:23
Moin Ha-Jö

Zitat:
Wenn ich das richtig verstehen dann gibt es keine "unbekannten" Prozeduren und Methoden sondern lediglich Objekte/Klassen die sich auf mehrere Units verteilen und die Du einheitlich aufrufen willst, Du weisst aber wo (in welcher Unit/Klasse) diese Funktionen ursprünglich definiert sind. Da du alle Methoden in Deinem Beispiel ohne Parameter aufrufen wolltest gehe ich davon aus das alle aufzurufenden Methoden paramterlos sind.
Richtig

Zitat:
... machst, dann kannst Du es auch gleich richtig machen und entweder Interfaces verwenden oder Dir einen Wrapper je aufzurufender Klasse schreiben und dessen Instanzen / Objekte registrieren.
Interfaces, Wrapper, ?, da hört es bei mir auf, das kann ich nicht

Ich glaub ich mach das mit den Fähnchen ...(Sparkasse)

Ich bin eher so der "Auto-Zusammen-Schrauber", sprich, fertige Komponenten
zusammenbauen, aber wenn es dann (für mich) ins "Eingemachte" geht muss
ich passen.

Aber vielen Dank für Deine Mühe !

cu

Sigi
  Mit Zitat antworten Zitat
Benutzerbild von stahli
stahli

Registriert seit: 26. Nov 2003
Ort: Halle/Saale
4.356 Beiträge
 
Delphi 11 Alexandria
 
#5

AW: Routine mit Namen aufrufen

  Alt 21. Feb 2015, 10:19
So wie ich das verstehe, liegt Dein Problem nicht bei "anderen Units" sondern bei "anderen Instanzen".
Zeig doch mal noch einen Auszug aus Deiner Datenbank, wie die Jobs definiert sind.

Wenn Du als JobNamen jetzt "DatensicherungStarten" ermittelst und dann in einem Objekt der Klasse TForm1 interpretierst um eine Methode "DatensicherungStarten" zu finden funktioniert das´, da Du Dich auf das Objekt "Self" beziehst.

Wenn Du aber mit einem anderen Objekt arbeiten willst, musst Du dessen Instanz mitgeben. Da reicht es nicht, eine Unit zu kennen.

Also ich denke, Du hast da noch einen Ansatz, der nicht ganz passt.

Versuch doch mal meinen oben genannten Ansatz. Offenbar hast Du ja nicht viele in Frage kommenden Möglichkeiten, welche Jobs aufgerufen werden können.
Dann könnte so ein "Übersetzer" schon Sinn machen. Du übergibst eine Objektinstanz und den Methodennamen und führst dann etwas passendes dazu aus.

Vom Prinzip könntest Du dann auch statt dem Methodennamen einen Code verwalten (42 = "DatensicherungStarten").

Dann siehst Du schon mal, dass Du eine Objektinstanz kennen musst, damit das funktionieren kann.

Ich denke, dass es derzeit bei Dir daran scheitert.


Zeig einfach noch ein bissl mehr, dann können wir das auch besser nachvollziehen.
Stahli
http://www.StahliSoft.de
---
"Jetzt muss ich seh´n, dass ich kein Denkfehler mach...!?" Dittsche (2004)
  Mit Zitat antworten Zitat
Sigi55

Registriert seit: 3. Jan 2010
36 Beiträge
 
Delphi 5 Professional
 
#6

AW: Routine mit Namen aufrufen

  Alt 21. Feb 2015, 11:39
Hallo Stali,

Zeig einfach noch ein bissl mehr, dann können wir das auch besser nachvollziehen.
Da löppelt einfach nur ne Schleife ...

Delphi-Quellcode:
while not eof do
begin
  ExecuteRoutine(Form1,dmLOG.tbl_JobsLinkedPreUpdate.FieldByName('Command').AsString);
  next;
end;
Das können ein- oder mehrere Jobs sein die nacheinander abgearbeitet
werden, z.B.: Angebote ausdrucken und versenden, Datenbanken abgleichen, etc.

Das ist auch nicht wirklich ein Problem, so wie es jetzt ist, ist es eigentlich
OK, aber ich dachte halt, ich könnte mir den quasi "doppelt gemoppelten" Aufruf
einer Procedure sparen, wenn die Procedure in irgendeiner anderen unit liegt.

Gruß

Sigi
  Mit Zitat antworten Zitat
Benutzerbild von BUG
BUG

Registriert seit: 4. Dez 2003
Ort: Cottbus
2.094 Beiträge
 
#7

AW: Routine mit Namen aufrufen

  Alt 21. Feb 2015, 19:58
Kann man über diesen Weg auch z.B. Destroy aufrufen*? Das konnte spaßig sein

* Sry, kein Delphi zur Hand.
  Mit Zitat antworten Zitat
BadenPower

Registriert seit: 17. Jun 2009
616 Beiträge
 
#8

AW: Routine mit Namen aufrufen

  Alt 21. Feb 2015, 20:42
Kann man über diesen Weg auch z.B. Destroy aufrufen*? Das konnte spaßig sein
[/SIZE]
Standardmäßig nicht, da der Destructor nur "public" ist.


Wenn Du das aber möchtest dann so:

Delphi-Quellcode:
type
  TForm1 = class(TForm)
    procedure Job1();
    procedure Button1Click(Sender: TObject);
  private
    procedure ExecuteJobs();
    procedure ExecuteRoutine(AInstance: TObject; AName: string);
  public
  published
    procedure Destroy;
  end;

var
  Form1: TForm1;

implementation

{$R *.dfm}

type
  TExecute = procedure of object;

procedure TForm1.Destroy;
begin
  inherited Destroy;
end;
Programmieren ist die Kunst aus Nullen und Einsen etwas sinnvollen zu gestalten.
Der bessere Künstler ist allerdings der Anwender, denn dieser findet Fehler, welche sich der Programmierer nicht vorstellen konnte.
  Mit Zitat antworten Zitat
Dejan Vu
(Gast)

n/a Beiträge
 
#9

AW: Routine mit Namen aufrufen

  Alt 22. Feb 2015, 07:44
Das Problem bei Ansätzen dieser Art(*) erblickt in seiner ganzen Wucht in dem Augenblick das Licht der Welt, in dem die Namen der aufzurufenden Prozeduren abgespeichert werden und anschließend ein Refactoring der Prozedurnamen erfolgt (= Methode umbenennen). Dann funktioniert nämlich gar nichts mehr.

Angenommen im Beispiel des TE kommt jemand auf die Idee, das '_' in Prozedurnamen ein NoGo sind (was nicht abwegig ist, denn sie sind es ). Eben wurde gespeichert, das 'Hello_World' aufgerufen werden soll, dann wird umbenannt und dann geht gar nichts mehr und im ungünstigsten Fall werden die abgespeicherten Aufrufe (als String) komplett unbrauchbar.

Alternativen? Z.B. Methodenattribute einführen, d.h. 'Hello_World' wird mit dem Attribute 'HELLOWORLD' dekoriert. Dann ist das Verfahren immun gegen Refactorings. Natürlich: Wer Attributparameter verändert, hat selbst schuld.

Mit Sicherheit gibt es bessere Ideen für eine robustere Umsetzung der Anforderung.

(*) Ein anderer Ansatz der gleichen Art: 'FindComponent'
  Mit Zitat antworten Zitat
hanvas

Registriert seit: 28. Okt 2010
171 Beiträge
 
Delphi 11 Alexandria
 
#10

AW: Routine mit Namen aufrufen

  Alt 22. Feb 2015, 10:59

Mit Sicherheit gibt es bessere Ideen für eine robustere Umsetzung der Anforderung.
Das war es doch was ich schon ansatzweise beschrieben (und den größten Teil des Überbaus gleich mitgeliefert) habe, indem man das Objekt welches die später aufzurufende(n) Methoden bereistellt diese selbst bei einer zentralen Instanz registrieren (und gff. deregistrieren) lässt, kann man die Methoden unter einem beliebigen Namen aufrufen, die Methode ist immun gegen Refactorings, relativ einfach und benötigt außer einer Liste keine weiteren Ressourcen, außerdem ist es nicht nötig das man die Objekte die Methoden bereitstellen von TForm oder TDataModule ableitet, möglich ist es natürlich trotzdem.

cu Ha-Jö
  Mit Zitat antworten Zitat
Antwort Antwort
Seite 1 von 2  1 2      


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 05:53 Uhr.
Powered by vBulletin® Copyright ©2000 - 2025, Jelsoft Enterprises Ltd.
LinkBacks Enabled by vBSEO © 2011, Crawlability, Inc.
Delphi-PRAXiS (c) 2002 - 2023 by Daniel R. Wolf, 2024-2025 by Thomas Breitkreuz