![]() |
Reguläre Prozedur in Methodenzeiger umwandeln
Liste der Anhänge anzeigen (Anzahl: 1)
Hallo,
ich habe mich - wie angekündigt - des Themas ![]() Wenn ich versuche, meine Prozedur mit exakt dem definierten Kopf zu übergeben, bekomme ich die Fehlermeldung
Delphi-Quellcode:
. Wenn ich den Lösungsvorschlag
E2009 Inkompatible Typen: 'Methodenzeiger und reguläre Prozedur'
![]() Es geht um folgenden Code(ausschnitt):
Delphi-Quellcode:
Wie löst man das Problem?
Program DirMon.nonVCL;
{$APPTYPE CONSOLE} Uses System.SysUtils, DirMonitor in '..\DirMonitor.pas'; Procedure ShowChange(Action: TAction; FileName: String); Var S : String; Begin S:= FormatDateTime('yyyy.mm.dd hh:nn:ss ', Now); Case Action Of faADDED : S:= '[ADD] "' + FileName + '"'; faREMOVED : S:= '[DEL] "' + Filename + '"'; faMODIFIED : S:= '[MOD] "' + FileName + '"'; faRENAMED_OLD_NAME: S:= '[REN] "' + FileName + '" (old name)'; faRENAMED_NEW_NAME: S:= '[REN] "' + FileName + '" (new name)'; End; WriteLn(S); End; Var T : TMethod; Run : Boolean = True; KeyBuffer : String = ''; KeyInput : Char; Begin Try T.Code:= @ShowChange; // <- https://www.entwickler-ecke.de/viewtopic.php?t=31378 With TDirMonitor.Create('C:\', TDirEvent(T)) Do // <- Ereignisse kommen nicht an With TDirMonitor.Create('C:\', ShowChange) Do // <- wird nicht kompiliert Try While Run Do // ständig wiederholen Begin Sleep(60); // kurz schlafen legen // Programm einfach am "Leben" erhalten ... End; Finally Free; // das Thread-Objekt freigeben End; Except On E: Exception Do Writeln(E.ClassName, ': ', E.Message); End; End. Ich habe allein in der DP 3 Funde zu diesem Thema gefunden und natürlich gelesen. Diese landen allesamt auf vorderen Plätzen bei der google-Suche. Aber ich komme auf keine Lösung. Die VCL-Variante klapp. Ich habe mal den Code als zip-Datei angehängt. |
AW: Reguläre Prozedur in Methodenzeiger umwandeln
Eine Methode gehört zu einer Klasse. Man löst das Problem also am einfachsten, indem man eine solche mit einer kompatiblen Methode deklariert, instanziert und dann das Event dieser Methode zuweist.
Delphi-Quellcode:
Sollte so in etwa funktionieren.
type
TMyClass = class public procedure ShowChange(Action: TAction; FileName: string); end; ... Monitor := nil; MyClass := TMyClass.Create; try Monitor := TDirMonitor.Create('C:\', MyClass.ShowChange); ... finally Monitor.Free; MyClass.Free; end; |
AW: Reguläre Prozedur in Methodenzeiger umwandeln
Die einzige, saubere Lösung ist, die Routine in eine Klasse zu packen und dann eine Instanz davon zu erzeugen.
Der Grund, warum man nicht einfach eine reguläre Prozedur in eine Methode casten kann, ist, dass bei der Methode immer ein impliziter Self-Parameter als erstes Argument übergeben wird.
Delphi-Quellcode:
wird intern zu
type
TFoobar = class procedure SayHello(Name: String); end; procedure TFoobar.SayHello(Name: String); begin WriteLn("Hello, ", Name); end;
Delphi-Quellcode:
Wenn du einfach castest, dann steht in den Parametern also nur Murks.
type
TFoobar = class end; procedure TFoobar_SayHello(Self: TFoobar, Name: String); begin WriteLn("Hello, ", Name); end; |
AW: Reguläre Prozedur in Methodenzeiger umwandeln
Danke DeddyH und Namenloser für die schnelle Hilfe.
Ich habe jetzt ein weiteres Problem, das evtl. nicht unmittelbar die Ausgangsfrage betrifft: Aus irgend einem Grund kommen die Ereignisse nicht an. D.h. genauer gesagt kommt immer nur ein Ereignis an. Aber auch das nicht während das Programm läuft, sondern erst wenn das Programm beendet wird. Das ist kurios, weil ich immer dasselbe Grundgerüst für solche Konsolenprogramme/-tests nutze und dort andere Komponenten wie z.B. die Indys - genauer deren Ereignisse - durchkommen. |
AW: Reguläre Prozedur in Methodenzeiger umwandeln
class methods (ohne static) können auch einer TMethod bzw einem Event zugewiesen werden, die haben nämlich auch den Self Pointer (in dem Fall auf die Klasse anstatt das Objekt).
|
AW: Reguläre Prozedur in Methodenzeiger umwandeln
Zitat:
Delphi-Quellcode:
mal bitte
while Run do
begin Sleep(); end;
Delphi-Quellcode:
var
Msg: TMsg; .. begin .. while GetMessage(Msg, 0, 0, 0) do begin TranslateMessage(Msg); DispatchMessage(Msg); end; |
Alle Zeitangaben in WEZ +1. Es ist jetzt 15:29 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