![]() |
Funktion über ihren Namen als String aufrufen
Hallo,
in manchem VBA kann man mit einem Funktionsnamen der als String vorliegt, diese Funktion aufrufen: CALL("MeineFunktion"). Weiß gerade nicht wie/ob man dabei auch Parameter übergeben kann, ist aber auch egal, da ich das nur ohne Parameter brauche. Die Frage ist natürlich, ob das auch in Delphi irgendwie geht. P.S.: Ich hab zwar wie ich gerade sehe überall Funktion geschrieben, meinte allerdings Prozedur.:oops: |
AW: Funktion über ihren Namen als String aufrufen
|
AW: Funktion über ihren Namen als String aufrufen
Mit Deinem Delphi 6 wird das so wohl nicht gehen. Bei neueren Versionen (ich glaub ab 2010) gibt es die RTTI.
|
AW: Funktion über ihren Namen als String aufrufen
Zitat:
|
AW: Funktion über ihren Namen als String aufrufen
OK. Wäre denn folgender Workarround denkbar / sinnvoll:
Es gibt eine Funktion oder eine Klasse mit u.a. einer Funktion. Dieser wird der Name einer anderen Funktion als String übergeben und diese startet dann über ein "If...then...else usw."-Konstrukt die gewünschte Funktion. Die Funktion muss natürlich alle diese Funktionen kennen und es wäre ggf. auch möglich Parameter zu übergeben (ist aber z.Zt. nicht wichtig). Also so etwas wie eine Factory für Funktionen? Zum Hintergrund: Bestimmte Funktionen sollen hintereinander ablaufen, die Ablaufreihenfolge soll aber veränderbar sein (über eine Tabelle gesteuert). |
AW: Funktion über ihren Namen als String aufrufen
Ja, warum denn nicht ...
Delphi-Quellcode:
procedure CallFunction( const AName : string; AParams : array of const; AResult : Variant );
var LName : string; begin AResult := Null; LName := LowerCase( AName ); if LName = 'tollefunktion' then tollefunktion else if LName = 'nochtollerefunktion' then nochtollerefunktion else raise Exception.CreateFmt( 'Funktion "%s" nicht gefunden!', [AName] ); end; |
AW: Funktion über ihren Namen als String aufrufen
Prima, danke für die Bestätigung.
|
AW: Funktion über ihren Namen als String aufrufen
Ich habe zwar das
![]() ![]() |
AW: Funktion über ihren Namen als String aufrufen
wenn Du den Link schon angibst:
Zitat:
|
AW: Funktion über ihren Namen als String aufrufen
Zitat:
Delphi-Quellcode:
type
TMyClass = class strict private _Value : string; private FValue : string; function GetValue : string; public function GetSomething( const AValue : string ) : string; property Value : string read GetValue; end; function TMyClass.GetValue : string; begin Result := '_' + FValue + '_'; end; function TMyClass.GetSomething( const AValue : string ) : string; var LValue : string; begin LValue := 'Something'; Result := LValue + // local variable AValue + // attribute _Value + // strict private class field FValue + // private class field Value; // property end; |
AW: Funktion über ihren Namen als String aufrufen
Puh, das wäre nicht mein Geschmack aber gut zu wissen :)
|
AW: Funktion über ihren Namen als String aufrufen
Wie man eine Funktion über ihren Namen als String aufruft ist mir nicht bekannt. Klassen lassen sich aber über den Namen erzeugen. Du könntest also deine Funktionen als Klassen abbilden und den auszuführenden Code im Constructor unterbringen. Einen Rückgabewert kannst du ggf. als Property definiern. Für eine ggf. nötige Parameter-Übergabe muss man sich noch was einfallen lassen, aber das geht bestimmt. Die Lösung ist aber ziemlich umständlich, vielleicht kann man dein Vorhaben mit einer Scripting-Engine besser umsetzen (evtl. JvInterpreter aus der JVCL).
Delphi-Quellcode:
Die Klassen müssen im initialization-Abschnitt mit RegisterClass(es) registriert werden:
uses
Classes; ... { -------------------------------------------------------------------------- } { TCsObjectCreator --------------------------------------------------------- } { -------------------------------------------------------------------------- } TCsObjectCreator = class(TObject) public class function CreateObjectByClassName(AClassName: String): TObject; class function CreateObjectByClassType(AClassType: TClass): TObject; class function FindClassByName(AClassName: String): TClass; end; { ---------------------------------------------------------------------------- } { TCsObjectCreator ----------------------------------------------------------- } { ---------------------------------------------------------------------------- } class function TCsObjectCreator.CreateObjectByClassName(AClassName: string): TObject; var MetaClass: TPersistentClass; begin MetaClass := TPersistentClass(Self.FindClassByName(AClassName)); Result := MetaClass.Create; end; class function TCsObjectCreator.CreateObjectByClassType(AClassType: TClass): TObject; begin Result := AClassType.Create; end; class function TCsObjectCreator.FindClassByName(AClassName: string): TClass; begin Result := FindClass(AClassName); end; Unit mit den "Funktionen":
Delphi-Quellcode:
Aufruf aus dem Programm:
TBaseFunction = class;
TTestFunction = class; TBaseFunctionClass = class of TBaseFunction; TBaseFunction = class(TPersistent) protected FResult: String; public class function GetClassName: String; virtual; published property Result: String read FResult; end; TTestFunction = class(TBaseFunction) public constructor Create; virtual; class function GetClassName: String; override; end; ... class function TBaseFunction.GetClassName: String; begin Result := 'TBaseFunction'; end; constructor TTestFunction.Create; begin FResult := 'Hallo Welt'; // irgendwas machen end; class function TTestFunction.GetClassName: String; begin Result := 'TTestFunction'; end; ... initialization RegisterClass(TTestFunction); // Edit: Evtl. muss der Parameter so aussehen: TPersistentClass(TTestFunction);
Delphi-Quellcode:
ungetestet
procedure TForm1.Button1Click(Sender: TObject);
var Func: TObject; begin // Objekt mittels String aus Edit1 erzeugen, constructor wird automatisch ausgeführt Func := TCsObjectCreator.CreateObjectByClassName(Edit1.text); // in text steht z. B. TTestFunction // Objekt wurde erzeugt und ist abgeleitet von Basisklasse? if Assigned(Func) and (Func is TBaseFunction) then begin // Rückgabewert der "Funktion" anzeigen (oder in Var speichern) ShowMessage(TBaseFunction(Func).Result); // Erzeugtes Objekt freigeben FreeAndNil(Func); end; end; |
AW: Funktion über ihren Namen als String aufrufen
Zumindest parameterlose published-Proceduren kann man so aufrufen:
Delphi-Quellcode:
Leider weiß ich nicht, seit welcher Delphi-Version es TMethod gibt, in Delphi 2007 ist sie jedenfalls bereits vorhanden.
procedure Call(AObject: TObject; const Methodname: string);
type TProc = procedure of object; var Method: TMethod; Proc: TProc; begin Method.Data := AObject; Method.Code := AObject.MethodAddress(Methodname); if Assigned(Method.Code) then begin Proc := TProc(Method); Proc; end; end; |
AW: Funktion über ihren Namen als String aufrufen
Zitat:
Delphi-Quellcode:
TForm1 = class(TForm) ... private FProcResult: String; FProcParams: Array of String; ... end; ... //var // ProcResult: String; // oder Variant, ... // ProcParams: Array of String; ... procedure TForm1.TestProc; begin if FProcParams[Low(FProcParams)] = 'Hallo' then FProcResult := 'Hallo' else FProcResult := 'Welt'; end; ... ButtonClick: begin // parameter festlegen SetLength(FProcParams, 1); FProcParams[1] := 'Hallo'; // Proc aufrufen Call(Self, 'TestProc'); // Rückgabewert anzeigen ShowMessage(FProcResult); end; |
AW: Funktion über ihren Namen als String aufrufen
Naja, wenn man aus Call eine (Klassen-)Methode macht, könnte man auf private (Klassen-)Felder zugreifen und somit auf globale Variablen verzichten.
|
AW: Funktion über ihren Namen als String aufrufen
Wenn man die Routinen in einer DLL vorhält, kann man diese zur Laufzeit unter ihrem Namen aufrufen.
Delphi-Quellcode:
Der Schnippsel ist aus einem Uralt-Projekt wo mit Plugins gearbeitet wurde.
Procedure CallProcedure (aDLLHandle : THandle; aFunctionName : String; aInParam : Variant; Var aOutParam : Variant);
Var pProcPtr: TDLLProcedure; Begin pProcPtr := GetProcAddress(aDLLHandle, PChar(aFunctionName)); If Not Assigned(pProcPtr) Then Raise Exception.CreateFmt('Function "%s" Not Found (%d)', [aFunctionName, GetLastError]); aOutParam := Null; pProcPtr(aInParam, aOutParam); End; |
AW: Funktion über ihren Namen als String aufrufen
Zitat:
|
Alle Zeitangaben in WEZ +1. Es ist jetzt 13:38 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 by Thomas Breitkreuz