Autor Beitrag
Christian213
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starontopic star
Beiträge: 66
Erhaltene Danke: 3

Win XP, Win 7 64Bit
Lazarus 1.0.10
BeitragVerfasst: Mo 24.06.13 11:05 
Hallo,

ich komme hier an einer Stelle nicht weiter. Ich verwende Lazarus in der aktuellen Version im Delphi-Modus.
Ich möchte gerne eine Prozedur mittels Übergabe einer Funktion als Parameter mehrfach verwenden.
Vom Prinzip her habe ich die Funktionsweise verstanden, leider scheint bei meiner Umsetzung noch ein Denkfehler drin zu sein:

Ich habe in der betroffenen Class eine Type-Definition:

type TFunctionParameter = function(const value1 : AnsiString; const value2 : AnsiString): boolean;

Diese wiederum benutze ich dann bei der Definition der Prozedur:

procedure Traverse(BaseDir: AnsiString; TargetDir: AnsiString; RelPath: AnsiString; _function: TFunctionParameter);

Innerhalb der Prozedur wird dann die übergebene Funktion _function mit Parametern aufgerufen.
Soweit, so gut.
Nun habe ich eine weitere Funktion, die ich als Funktions-Parameter übergeben möchte um damit die Prozedur "Traverse" aufzurufen:

function CopyIfNewer(Source: AnsiString; Target: AnsiString): boolean;

Wenn ich die Beispiele richtig verstanden habe, muss ich dazu nur den Funktionsnamen ohne Parameter übergeben:

Traverse('...', '...', '...', CopyIfNewer);

Hier meckert der Compiler dann aber:

Error: Incompatible type for arg no. 4: Got "TNovaUtils.TNovaUtils.CopyIfNewer(AnsiString,AnsiString):Boolean;", expected "TNovaUtils.<procedure variable type of function(const AnsiString,const AnsiString):Boolean;Register>"
Hint: Found declaration: TNovaUtils.Traverse(AnsiString,AnsiString,AnsiString,TFunctionParameter);

Meine Frage: Warum? Und wie macht man es richtig??

Danke! :-)
WasWeißDennIch
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starontopic star
Beiträge: 653
Erhaltene Danke: 160



BeitragVerfasst: Mo 24.06.13 11:13 
Und wenn Du die Parameter von CopyIfNewer auch als Konstanten deklarierst?

Für diesen Beitrag haben gedankt: Christian213
Gammatester
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starhalf ontopic star
Beiträge: 328
Erhaltene Danke: 101



BeitragVerfasst: Mo 24.06.13 11:18 
Du must die Parameter konsistent benutzen. Also

ausblenden Delphi-Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
// Entweder beide mit const
type TFunctionParameter = function(const value1 : AnsiString; const value2 : AnsiString): boolean; 
//und
function CopyIfNewer(const Source: AnsiString; const Target: AnsiString): boolean; 

//oder beide ohne const

type TFunctionParameter = function(value1 : AnsiString; value2 : AnsiString): boolean; 
//und
function CopyIfNewer(Source: AnsiString; Target: AnsiString): boolean;

Für diesen Beitrag haben gedankt: Christian213
Christian213 Threadstarter
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starontopic star
Beiträge: 66
Erhaltene Danke: 3

Win XP, Win 7 64Bit
Lazarus 1.0.10
BeitragVerfasst: Mo 24.06.13 11:26 
Hallo,

Danke für die Antworten.
Das hatte ich auch schon ausprobiert, es ändert sich aber nicht wirklich viel dann:

Error: Incompatible type for arg no. 4: Got "TNovaUtils.TNovaUtils.CopyIfNewer(AnsiString,AnsiString):Boolean;", expected "TNovaUtils.<procedure variable type of function(AnsiString,AnsiString):Boolean;Register>"

Dieses "procedure variable type of function" und das ";Register" verwirren mich...
WasWeißDennIch
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starontopic star
Beiträge: 653
Erhaltene Danke: 160



BeitragVerfasst: Mo 24.06.13 11:27 
Kann es sein, dass CopyIfNewer eine Methode einer Klasse TNovaUtils ist?

Für diesen Beitrag haben gedankt: Christian213
Christian213 Threadstarter
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starontopic star
Beiträge: 66
Erhaltene Danke: 3

Win XP, Win 7 64Bit
Lazarus 1.0.10
BeitragVerfasst: Mo 24.06.13 11:33 
user profile iconWasWeißDennIch hat folgendes geschrieben Zum zitierten Posting springen:
Kann es sein, dass CopyIfNewer eine Methode einer Klasse TNovaUtils ist?


Ja, ist es. Es sind alles "Mitglieder" dieser Klasse. Inklusive der Type-Definition.
Ich hatte das nur beim Copy&Paste weggeschnitten.
WasWeißDennIch
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starontopic star
Beiträge: 653
Erhaltene Danke: 160



BeitragVerfasst: Mo 24.06.13 11:36 
Dann versuch es mal mit
ausblenden Delphi-Quelltext
1:
type TFunctionParameter = function(const value1 : AnsiString; const value2 : AnsiString): boolean of object;					

Für diesen Beitrag haben gedankt: Christian213
Christian213 Threadstarter
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starontopic star
Beiträge: 66
Erhaltene Danke: 3

Win XP, Win 7 64Bit
Lazarus 1.0.10
BeitragVerfasst: Mo 24.06.13 11:41 
user profile iconWasWeißDennIch hat folgendes geschrieben Zum zitierten Posting springen:
Dann versuch es mal mit
ausblenden Delphi-Quelltext
1:
type TFunctionParameter = function(const value1 : AnsiString; const value2 : AnsiString): boolean of object;					


Damit geht's! Dankeschön! :-)
Das i-Tüpfelchen wäre nun, wenn Du mir noch kurz erklären könntest wieso hier ein "of object" hinter stehen muss.
WasWeißDennIch
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starontopic star
Beiträge: 653
Erhaltene Danke: 160



BeitragVerfasst: Mo 24.06.13 11:44 
Weil es sich um eine Methode handelt. Methoden gehören ja zu einem Objekt (genauer: einer Instanz), daher das "of object", während die sog. regulären Prozeduren/Funktionen für sich alleine stehen.

Für diesen Beitrag haben gedankt: Christian213
Christian213 Threadstarter
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starontopic star
Beiträge: 66
Erhaltene Danke: 3

Win XP, Win 7 64Bit
Lazarus 1.0.10
BeitragVerfasst: Mo 24.06.13 11:53 
Okay, dann habe ich es verstanden, denke ich.
Danke für die tolle und schnelle Hilfe hier! :-)

Gruß,
Christian
jaenicke
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starofftopic star
Beiträge: 19312
Erhaltene Danke: 1747

W11 x64 (Chrome, Edge)
Delphi 11 Pro, Oxygene, C# (VS 2022), JS/HTML, Java (NB), PHP, Lazarus
BeitragVerfasst: Mo 24.06.13 13:52 
Um mal den Hintergrund zu erklären:
Eine Methode besteht intern aus zwei Werten, dem Zeiger auf die Methode selbst (Code) und einem Zeiger auf das dazugehörige Objekt (Daten). Wenn die Methode aufgerufen wird, wird dieser zweite Zeiger für Zugriffe auf das Objekt benutzt, z.B. Zugriffe auf private Felder.

Eine Prozedur ohne Objekt ist ein einfacher Zeiger auf die Prozedur.

Und eine anonyme Methode beinhaltet zusätzlich zum Methodenzeiger noch Daten zum Scope zum Zeitpunkt des Erstellens der Methode, damit z.B. dort vorhandene lokale Variablen erst aufgeräumt werden, wenn auch die anonyme Methode samt Scope beendet ist.

Für diesen Beitrag haben gedankt: Christian213
OlafSt
ontopic starontopic starontopic starontopic starontopic starontopic starhalf ontopic starofftopic star
Beiträge: 486
Erhaltene Danke: 99

Win7, Win81, Win10
Tokyo, VS2017
BeitragVerfasst: Mo 24.06.13 17:22 
user profile iconjaenicke hat folgendes geschrieben Zum zitierten Posting springen:
Um mal den Hintergrund zu erklären:
Eine Methode besteht intern aus zwei Werten, dem Zeiger auf die Methode selbst (Code) und einem Zeiger auf das dazugehörige Objekt (Daten). Wenn die Methode aufgerufen wird, wird dieser zweite Zeiger für Zugriffe auf das Objekt benutzt, z.B. Zugriffe auf private Felder.


Oder anders formuliert: Methodenaufrufe haben immer einen versteckten ersten Parameter, der auf das Objekt selbst zeigt. Darum muß "of object" angegeben werden, damit der Compiler weiß "Aha, das ist ne Methode, ergo kommt da als erstes ein versteckter Parameter".

_________________
Lies, was da steht. Denk dann drüber nach. Dann erst fragen.

Für diesen Beitrag haben gedankt: Christian213