Delphi-PRAXiS

Delphi-PRAXiS (https://www.delphipraxis.net/forum.php)
-   Object-Pascal / Delphi-Language (https://www.delphipraxis.net/32-object-pascal-delphi-language/)
-   -   Delphi funktion aufrufen deren namen in einem string steckt (https://www.delphipraxis.net/136657-funktion-aufrufen-deren-namen-einem-string-steckt.html)

griever 5. Jul 2009 11:58


funktion aufrufen deren namen in einem string steckt
 
mit findcompnent kann man ja ziemlich praktisch auf eine componente zugreifen deren name in einem string steht.
nun meine frage: gibts das auch für funktion/proceduren bzw eine alternative dazu?

ich habe mir überlegt, das man ja theoretisch eine eigene componente machen könnte, die halt unterschiedlich benannte wird und dann unterschiedlich funktionen ausführt. finde das aber umständlich, weil man dann ja jede funktion anders typisieren müsste.

Apollonius 5. Jul 2009 12:03

Re: funktion aufrufen deren namen in einem string steckt
 
Funktionsnamen sind im Kompilat nicht mehr erhalten - von etwaigen Debuginformationen einmal abgesehen. Also: unmöglich. Du könntest allerdings auf Methoden umsteigen, die du im published-Abschnitt deklarierst: Diese Namen sind in der RTTI gespeichert. Siehe TObject.MethodAddress.

himitsu 5. Jul 2009 12:09

Re: funktion aufrufen deren namen in einem string steckt
 
Da Delphi keine Namen von Funktionen speichert, ist das so nicht möglich.

Einzige Möglichkeiten:
- definier sie als Published in einer Klasse, dann kann man dank RTTI diese auflisten
- verwende ein Array, wo die Zeiger zu den Funktionen und ihr Name drin aufgelistet wurden (natürlich von dir selber) und such dann einfach dieses Array ab
- und maximal noch die Exports-Liste (ja, die gibt es auch bei einer EXE und nicht nur bei DLLs :mrgreen: )

[edit]
Apollonius war schneller :( , aber ich hab mehr :tongue:

griever 5. Jul 2009 15:09

Re: funktion aufrufen deren namen in einem string steckt
 
also ich versuch grad die Pointer der funktionen abzuspeichern und danach aufzurufen ... was mich wieder zum problem führt das 1.:
ich ja den inhalt des strings nicht einfach als name für den index des array setzen kann
bsp im string steht: 'abc'
und im array sollte dann stehen :
abc := @funktion();
abcd := @anderefunktion();
2.der index ja eine zahl sein muss

Meflin 5. Jul 2009 15:15

Re: funktion aufrufen deren namen in einem string steckt
 
-> Dann leg dir eine Hashtable an, die sind genau dafür gedacht. Du iwrst im forum fertige implementationen dafür finden. Dann kannst du unter einem "Stringindex" was abspeichern - in deinem Fall eben nen Methodenzeiger ;)

himitsu 5. Jul 2009 15:22

Re: funktion aufrufen deren namen in einem string steckt
 
Delphi-Quellcode:
Array of record
  Name: String;
  Proc: Prozedure(a: irgendwas);
end;
da kannst du alles reinpacken und in einen Schleifchen die Namen prüfen

oder TIntegerDictionaryTIntegerDictionary Hier im Forum suchenTStringDictionary oder auch Hier im Forum suchenTAssocArray :mrgreen:
('ner einfach "unveränderliche" Version befindet sich in himXML_Tools.pas > Hier im Forum suchenhimXML)

griever 5. Jul 2009 15:38

Re: funktion aufrufen deren namen in einem string steckt
 
also ich hab jetzt mal stark vereinfach nen normales array genommen und an 1. stelle will den pointer der funktion schreiben nur wenn ich
array[1] := @funktion(parameter1,parameter2) schreibe kommt ne fehlermeldung :
[Pascal Error] Unit1.pas(54): E2036 Variable required
wenn ich die parameter weglasse funktioniert es nur kann die funktion dann ja nichts machen.

das mit dem array of record würde ja wieder dazuführen das ich immerwieder das array nach dem namen durchsuchen müsste ich wollte aber gleich an die stelle springen

himitsu 5. Jul 2009 16:01

Re: funktion aufrufen deren namen in einem string steckt
 
was willst du auch die Parameter da schon angeben, wo du siese doch erst später angeben wolltest?

außerdem wird bei Angabe von Parametern die Funktion ausgeführt und nicht ein Zeiger auf diese geliefert.
Delphi-Quellcode:
type TMyFunc = function(b: Byte);
  TMyArray = array of record
    name: String;
    func: TMyFunc;
  end;
var a: TMyArray;

function TestFunc(b: Byte);
begin
end;


SetLength(a, 1);
a[0].func := TestFunc;

x := a[0].func(123);
[add]
Zitat:

Zitat von griever
das mit dem array of record würde ja wieder dazuführen das ich immerwieder das array nach dem namen durchsuchen müsste ich wollte aber gleich an die stelle springen

egal was du machst, irgendwer muß immer irgendeine Liste durchsuchen, ob das nun du selber machst, oder irgendeine Komponente für dich.

griever 5. Jul 2009 16:17

Re: funktion aufrufen deren namen in einem string steckt
 
Zitat:

Zitat von himitsu
egal was du machst, irgendwer muß immer irgendeine Liste durchsuchen, ob das nun du selber machst, oder irgendeine Komponente für dich.

aber wenn ich nen normales array nehme und dort array[129] abfrage, werden doch nicht erst die 128 vorher überprüft ob sie = 129 sind und dann bei = 129 der wert ausgegeben oder?

himitsu 5. Jul 2009 16:27

Re: funktion aufrufen deren namen in einem string steckt
 
Die Zahl wird von Delphi direkt verrechnet, da sie ja selber den Index/Offset darstellt.

Delphi macht also aus array[129] z.B. (@array + 129*SizeOf(Element))^, aber mit einem String ist sowas nicht möglich.

griever 5. Jul 2009 16:35

Re: funktion aufrufen deren namen in einem string steckt
 
ok das ergibt sinn
dann fällt mir jetzt nur noch ein das ich den inhalt des strings als name für die variable (welche den pointer auf die funktion hat) z.B.:
string := 'abc';
abc := @funktion;

nur wie komme ich jetzt mit den namen der variablen im string an deren inhalt?

himitsu 5. Jul 2009 16:42

Re: funktion aufrufen deren namen in einem string steckt
 
Zitat:

Zitat von griever
nur wie komme ich jetzt mit den namen der variablen im string an deren inhalt?

siehe oben


Delphi-Quellcode:
type TMyFunc = function(b: Byte);
  TMyArray = array of record
    name: String;
    func: TMyFunc;
  end;
var a: TMyArray;

function TestFunc(b: Byte);
begin
end;


SetLength(a, 1);
a[0].name := 'Test';
a[0].func := TestFunc; // 1

for i := 0 to High(a) do
  if a[i].name = {'Test'} then begin
    x := a[i].func({123});
    Break;
  end;
1: falls sich da wer wundert, daß dort nicht @TestFunk steht ... Delphi erkennt, daß Links ein Funktionszeiger erwartet wird und weiß, daß ich den Zeiger zur Funktion zuweisen will.

griever 5. Jul 2009 17:08

Re: funktion aufrufen deren namen in einem string steckt
 
ok bin mir sicher das das funktioniert aber gibt es keinen befehl in delphi der direkt den inhalt eines stringes als name umwandelt (außer das findcomponents) weil sonst kann ich auch gleich
if string = 'abc' then abc(a,b); machen nur find ich das nicht "optional"

jfheins 5. Jul 2009 17:17

Re: funktion aufrufen deren namen in einem string steckt
 
Erstelle eine Superklasse, die alle Methoden als published Property hat - dann kannst du mit der RTTI darauf zugreifen und eine Methode aufrufen, deren namen du im String hast.

Was soll das eigentlich mal werden? Vll. gibts da bessere Lösungen ...

himitsu 5. Jul 2009 18:43

Re: funktion aufrufen deren namen in einem string steckt
 
Zitat:

Zitat von griever
ok bin mir sicher das das funktioniert aber gibt es keinen befehl in delphi der direkt den inhalt eines stringes als name umwandelt (außer das findcomponents) weil sonst kann ich auch gleich if string = 'abc' then abc(a,b); machen nur find ich das nicht "optional"

Was denkst du eigentlich, was FindComponent macht?

Das geht auch nur die in der Form registrierten Komponenten durch, welche auch in einer Art Array/Liste dort gespeichert sind.
Delphi-Quellcode:
function TComponent.FindComponent(const AName: string): TComponent;
var
  I: Integer;
begin
  if (AName <> '') and (FComponents <> nil) then
    for I := 0 to FComponents.Count - 1 do
    begin
      Result := FComponents[I];
      if SameText(Result.FName, AName) then Exit;
    end;
  Result := nil;
end;

Uwe Raabe 5. Jul 2009 19:51

Re: funktion aufrufen deren namen in einem string steckt
 
Es ist zwar schon mehrfach angesprochen worden, aber hier mal ein konkretes Beispiel. Der Einfachheit halber geben die Funktionen lediglich einen Integer-Wert zurück:

Delphi-Quellcode:
type
  TMyFunc = function: Integer of object;

function CallObjectFunction(Instance: TObject; const FuncName: string): Integer;
var
  Func: TMyFunc;
  MVar: TMethod;
begin
  MVar.Data := Instance;
  MVar.Code := Instance.MethodAddress(FuncName);
  Assert(Assigned(MVar.Code));
  Func := TMyFunc(MVar);
  result := Func();
end;

type
{$METHODINFO ON}  // falls das nicht geht, müssen die Methoden published sein!
  TTestObject = class
  public
    function Test1: Integer;
    function Test2: Integer;
  end;

function TTestObject.Test1: Integer;
begin
  result := 42;
end;

function TTestObject.Test2: Integer;
begin
  result := 4711;
end;

procedure TestIt;
var
  res: Integer;
  TestObject: TTestObject;
begin
  TestObject := TTestObject.Create;
  try
    res := CallObjectFunction(TestObject, 'Test1');
    Assert(res = 42);
    res := CallObjectFunction(TestObject, 'Test2');
    Assert(res = 4711);
  finally
    TestObject.Free;
  end;
end;

himitsu 5. Jul 2009 20:25

Re: funktion aufrufen deren namen in einem string steckt
 
Und .MethodAddress macht genau das Selbe wie die anderen Vorschläge ... es durchsucht eine Liste nach den Namen und gibt einen Zeiger auf dessen zugeordnete Funktion zurück.

Blup 7. Jul 2009 13:32

Re: funktion aufrufen deren namen in einem string steckt
 
Abhilfe schafft nur ein Precompiler, wie er z.B. in den meisten Basic-Dialekten eingesetzt wird.
Dieser würde die Funktionsaufrufe durch Token mit der entsprechenden Adresse oder Nummer ersetzen.
Dadurch wird dann die eigentliche Ausführung schneller.


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