Delphi-PRAXiS

Delphi-PRAXiS (https://www.delphipraxis.net/forum.php)
-   Object-Pascal / Delphi-Language (https://www.delphipraxis.net/32-object-pascal-delphi-language/)
-   -   Delphi Funktionsnamen aus INI-Datei (o.ä.) importieren (https://www.delphipraxis.net/10815-funktionsnamen-aus-ini-datei-o-ae-importieren.html)

grinch_ac 25. Okt 2003 19:21


Funktionsnamen aus INI-Datei (o.ä.) importieren
 
Ich habe folgendes Problem, an dem ich mir zur Zeit einen Knoten ins Hirn denke :gruebel: :

Ich habe eine Klasse TStringConverter erstellt, die eine Reihe von Funktionen enthält, die mir Strings in allen möglichen Formen umformatieren sollen (z.B. Währungen, HTML-Code, Gross-Klein etc.) und auch wieder als String zurückgibt.

Die umzuformatierenden Strings kommen aus INI- oder Textdateien. Jetzt wollte ich jeweils zu jedem dieser Strings gleich den Funktionsnamen als Info mitgeben, mit welcher Funktion er umkonvertiert werden soll, damit ich nicht für jede Änderung an der INI das Programm neu kompilieren muss.

Ich dachte daran, aus dem Namen der auszuführenden Funktion (als Variable vom Typ string aus der INI eingelesen) irgendwie auf einen Methodenzeiger zu kommen, aber komme nicht so recht weiter.

Gibt es eine Möglichkeit, wenn ich eine Instanz der Klasse TStringConverter und die Variable vom Typ string mit dem Namen der auszuführenden Funktion habe, daraus einen Funktionsaufruf zu generieren? Vielleicht ist es ja ganz einfach und ich habe die letzten Tage zuviel Frischluft geatmet, aber ich komm' einfach nicht weiter :wall: . Bin für jede Anregung dankbar.

Gruss
Dirk

Chewie 25. Okt 2003 19:39

Re: Funktionsnamen aus INI-Datei (o.ä.) importieren
 
Falls die Methode published deklariert ist, kannst du mal TObject.MethodAddress versuchen.

grinch_ac 26. Okt 2003 15:44

Re: Funktionsnamen aus INI-Datei (o.ä.) importieren
 
Prima Idee, ich habe das jetzt mal versucht, es sieht auch soweit ganz gut aus, allerdings bekomme ich beim Aufruf der Funktion eine Zugriffsverletzung ("Zugriffsverletzung bei Adresse xxxxxx in Modul 'Test.exe', Lesen von Adresse yyyyyy"), der Debugger steht dabei in der ersten Zeile der aufzurufenden Funktion 'MachNix', d.h. gefunden hat er sie wohl schon :) . Was mache ich jetzt dabei falsch? Muss ich noch irgenwelche anderen Parameter oder Pointer initialsieren? Bis jetzt sieht das Ganze so aus:

Delphi-Quellcode:
type
  TConvertFunction = function(Param: string): string of object;
  TStringConverter = class(TObject)
  published
    function Convert(func, Param: string): string; //  <=== Diese Funktion wird von aussen mit dem
                                                    //       Namen der Funktion (func) und dem an
                                                    //       die Funktion zu übergebenden String-
                                                    //       Parameter (Param) aufgerufen
    function MachNix(Param: string): string;
  end;

implementation

{ TStringConverter }

function TStringConverter.convert(func, Param: string): string;
var
  PConvertFunc: Pointer;
  FConvertFunc: TConvertFunction;
begin
  @FConvertFunc:= nil;
  PConvertFunc:= self.MethodAddress(func);
  @FConvertFunc:= PConvertFunc;
  if assigned(FConvertFunc)        //           <=== das klappt noch
  then
    result:= FConvertFunc(Param)   //           <=== und dabei knallt's
  else
    result:= 'invalid function call: '+func;
end;

function TStringConverter.MachNix(Param: string): string;
begin
  result:= Param;                  //           <=== hier steht dann der Debugger mit der Exception
end;
Der Aufruf von aussen sieht in etwa so aus und klappt auch:

Delphi-Quellcode:

TTestThread.execute
var
  FStrConv: TStringConverter;
  S,T: string;
begin
  S:= 'Hallo';
  T:= 'Huhu';
  FStrConv:= TStringConverter.Create();
  T:= FStrConv.Convert('MachNix',S);
end;

Christian Seehase 26. Okt 2003 16:27

Re: Funktionsnamen aus INI-Datei (o.ä.) importieren
 
Moin Grinch,

so geht's:

Delphi-Quellcode:
function TStringConverter.convert(func, Param: string): string;

var
  FConvertFunc: TConvertFunction;

begin
  @FConvertFunc:= self.MethodAddress(func);
  if assigned(FConvertFunc)
  then
    result:= FConvertFunc(Param)
  else
    result:= 'invalid function call: '+func;
end;

function TStringConverter.MachNix(Param: string): string;
begin
  result:= Param;
end;

procedure TForm1.Button1Click(Sender: TObject);

var
  sc : TStringConverter;

begin
  sc := TStringConverter.Create;
  try
    ShowMessage(sc.Convert('machnix','HALLO'));
  finally
    FreeAndNil(sc);
  end;
end;

grinch_ac 27. Okt 2003 14:46

Re: Funktionsnamen aus INI-Datei (o.ä.) importieren
 
Jawoll, so klappts... :hello:
Danke!

Was mir allerdings noch nicht klar ist, warum gehts so nicht:

Delphi-Quellcode:
  PConvertFunc:= self.MethodAddress(func);
  @FConvertFunc:= PConvertFunc;
und so schon:

Delphi-Quellcode:
  @FConvertFunc:= self.MethodAddress(func);
Sollte doch dasselbe sein, oder :gruebel: ?

Christian Seehase 27. Okt 2003 16:15

Re: Funktionsnamen aus INI-Datei (o.ä.) importieren
 
Moin Grinch,

die andere Version funktioniert bei mir auch.


Alle Zeitangaben in WEZ +1. Es ist jetzt 01:34 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