![]() |
Prozedur aufrufen
Hallo,
noch jemand wach ? cool. danke. Ich habe folgendes prob: ich will einen Pointer entgegennehmen der auf eine existierende Prozedur zeigt.
Delphi-Quellcode:
ok den Pointer über geb ich mit
procedure entgegennehmen(procptr: Pointer);
Delphi-Quellcode:
So aber wie ruf ich diese Prozedur am andern ende des Pointers auf und vor allem wie übergeb ich der Parameter ???
entgegennehmen(@meineprozedur);
PS: Windows kann das ( Siehe EnumWindows( EnumProc: Pointer;..) |
Re: Prozedur aufrufen
Zuerst brauchst Du eine Deklaration des übergebenen Prozedurtyps:
Delphi-Quellcode:
Damit besteht dann die Möglichkeit den übergebenen Pointer auszuwerten:
type
TMyProc = procedure(const Value: string);
Delphi-Quellcode:
MfG,
procedure Entgegennehmen(ProcPtr: Pointer);
var MyProc: TMyProc; begin @MyProc := ProcPtr; MyProc('42'); end; Tryer |
Re: Prozedur aufrufen
hey cool danke.
kann ich die übergebenen parameter vielleicht auch allgemein halten ( als array ? so dass man alle möglichen Prozeduren mit den entsprechenden Parametern aufrufen kann ? der Format-Befehl nimmt auch so ne array entgegen |
Re: Prozedur aufrufen
Schau mal in der OH, oder hier nach Variant (z.B. Variante Arrays, Variante Typen ...)
|
Re: Prozedur aufrufen
Warum nicht gleich...
Delphi-Quellcode:
??
procedure Entgegennehmen(ProcPtr: TMyProc);
begin ProcPtr('42'); end; |
Re: Prozedur aufrufen
ich speichere die Parameter und rufe die Prozedur nach einem anegegebenen Zeitintervall wieder auf.
Wenns gar nich will werde ich wohl bisschen assemblern müssen ( der die Parameter werden in form eines Stacks in EBP übergeben); dann muss ich eigentlich nur die Werte ( Pointer oder vielleicht sinds auch schon integer oder andere 32bit werte) retten, in ner Array speichern, dann wieder auf den stack pushen und die Prozedur aufrufen ? :roll: Jemand ne Ahnung ob das so geht ? |
Re: Prozedur aufrufen
Delphi Hilfe :warn:
Bei Verwendung der Konventionen pascal, cdecl, stdcall und safecall werden alle Parameter im Stack übergeben. Bei der Konvention pascal werden die Parameter in der Reihenfolge ihrer Deklaration (von links nach rechts) übergeben, so dass der erste Parameter im Stack an der obersten Adresse und der letzte Parameter an der untersten Adresse gespeichert wird. Bei den Konventionen cdecl, stdcall und safecall werden die Parameter in der entgegengesetzten Reihenfolge ihrer Deklaration (von rechts nach links) übergeben, so dass der erste Parameter im Stack an der untersten Adresse und der letzte an der obersten Adresse gespeichert wird. Bei der Konvention register werden maximal drei Parameter in den CPU-Registern übergeben, der Rest im Stack. Die Parameter werden in der Reihenfolge ihrer Deklaration übergeben (wie bei der Konvention pascal). Die ersten drei geeigneten Parameter stehen in den Registern EAX, EDX und ECX (in dieser Reihenfolge). Nur reelle, variante und strukturierte Typen sowie Methodenzeiger- und Int64-Typen sind als Registerparameter ungeeignet. Sind mehr als drei mögliche Registerparameter vorhanden, werden die ersten drei in EAX, EDX und ECX übergeben. Die restlichen Parameter werden in der Reihenfolge ihrer Deklaration im Stack abgelegt. Ein Beispiel: procedure Test(A: Integer; var B: Char; C: Double; const D: string; E: Pointer); |
Re: Prozedur aufrufen
aber wie bring ich jetzt die parameter auf den Stack ?
push EBP ? geht das nicht einfacher ? und muss ich so nicht für jeden typ unterscheiden ? |
DP-Maintenance
Dieses Thema wurde von "Christian Seehase" von "Windows API" nach "Sonstige Fragen zu Delphi" verschoben.
Geht um Delphi Interna, nicht Windows |
Re: Prozedur aufrufen
hat jemand eine Idee wie ich die parameter übergeb ?
|
Re: Prozedur aufrufen
Moin HBoy,
was gefällt Dir denn an Tryers bzw. Maximovs Variante nicht? Funktioniert doch. |
Re: Prozedur aufrufen
ich will die parameter allgemein halten. Deswegen kann ich keine Typen definiern
|
Re: Prozedur aufrufen
Moin HBoy,
dann schau Dir mal in der Hilfe "Variante offene Array-Parameter" an, falls die Parameter einen unterschiedlichen Typ haben können, oder aber "Offene Array-Parameter" falls der Typ immer gleich ist. |
Re: Prozedur aufrufen
Danke für deine Antwort aber das ist nicht mehr das Problem. mittlerweile kann ich die parameter in einer array vom typ TVarRec ( ja glaub so hießt der ) speichern. Das ist der Typ den Delphi für Const einsetzt. Array of const = array of TVarRec.
Mein problem ist jetzt nur wie ich die Prozedur aufrufen kann und ihr die Array übergeb. Kann ich vielleicht einen Prozedurtyp procedure fitsall( Array of TVarRec) of object bauen ? |
Re: Prozedur aufrufen
Ich hab das jetzt so:
Delphi-Quellcode:
allerdings bekomme ich die Parameter nicht korrekt zurück. Geladen werden sie so:
type UniProc = procedure(const params: Array of const );
procedure CallProc( procptr: Pointer; const paramlist: Array of const); var x: UniProc; begin x := procptr; x(paramlist); end;
Delphi-Quellcode:
procedure SetTimeout(proc: Pointer;const params: Array of const; msecs: longword);
var i: integer; begin setlength(jobs,length(jobs)+1); jobs[high(jobs)].proc := proc; setlength(jobs[high(jobs)].params,length(params)); for i :=0 to high(params) do begin jobs[high(jobs)].params[i] := params[i]; end; jobs[high(jobs)].launchtime := gettickcount+msecs; end; |
Re: Prozedur aufrufen
Weiß jemand wieso das nicht tut ?
|
Re: Prozedur aufrufen
kleines Textbeispiel:
procedure setformtitle(x: integer); begin form1.caption := inttostr(x); end; procedure TForm1.Button1Click(Sender: TObject); begin SetTimeout(@setformtitle,[23],1000); end; damit müsste nach 1 sekunde "23" dranstehn, anstelle dessen kommt aber 23409217 oder eine anderer nicht initialisierter Wert Jemand ne Ahnung warum ? muss ich für den typ TVarRec erst den Speicher reservieren ? |
Re: Prozedur aufrufen
*nochmal auf mein problem hinweis* weißes niemand ?
|
Re: Prozedur aufrufen
Moin hboy,
wie sieht die Deklaration von "Jobs" aus? |
Re: Prozedur aufrufen
Delphi-Quellcode:
könnte vielleicht an der dny. Array liegen
type queuejob = record
proc: Pointer; params: Array of TVarRec; launchtime: longword; processed: boolean; end; var obj: TTimeout; jobs: Array of queuejob; |
Re: Prozedur aufrufen
Moin hboy,
irgendwie fehlt jetzt noch was Entscheidendes. Könntest Du bitte mal das Projekt (nur die Sourcen) als Attachement dranhängen? Der eigentliche Funktionsaufruf fehlt ja noch. |
Re: Prozedur aufrufen
Moin hboy,
jetzt hab' ich's. Du musst natürlich der Funktion die Du aufrufst auch den Parameter mitgeben den sie braucht bzw. erwartet. Z.B. so
Delphi-Quellcode:
Oder Du ermittelst vor dem Aufruf, was die Funktion braucht und übergibst dann den entsprechenden Teil der Parameterliste, die Du zu dem Job gespeichert hast.
procedure setformtitle(x: array of const);
begin form1.caption := inttostr(x[0].VInteger); end; |
Re: Prozedur aufrufen
:cry: schon mal nicht schlecht aber es soll auch bei sowas funktionieren:
Delphi-Quellcode:
da es allgemein sein soll. die parameterübergabe und typendeklaration is bei Delphi eben bissle tricky.
procedure verschiedeneparams(a: string; b: longint);
begin form1.caption := a+inttostr(b); ennd; setTimeout(@verschiedeneparams, ['blabla: ',23],1000); :arrow: die Prozedur die entgegennimmt so keine Array haben müssen und wiederum die Parameter prüfen müssten. tnx for answering. :hi: |
Alle Zeitangaben in WEZ +1. Es ist jetzt 22:13 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