AGB  ·  Datenschutz  ·  Impressum  







Anmelden
Nützliche Links
Registrieren

Reguläre Prozedur in Methodenzeiger umwandeln

Ein Thema von Schwedenbitter · begonnen am 24. Mai 2017 · letzter Beitrag vom 26. Mai 2017
Antwort Antwort
Schwedenbitter

Registriert seit: 22. Mär 2003
Ort: Finsterwalde
622 Beiträge
 
Turbo Delphi für Win32
 
#1

Reguläre Prozedur in Methodenzeiger umwandeln

  Alt 24. Mai 2017, 15:48
Hallo,

ich habe mich - wie angekündigt - des Themas Verzeichnisüberwachung angenommen und das ganze ohne TObject in einen Thread gepackt. In einer Windows-Anwendung mit VCL klappt das ganze prima. Ich brauche es aber für die Konsole und da geht "der Spaß" erst richtig los.
Wenn ich versuche, meine Prozedur mit exakt dem definierten Kopf zu übergeben, bekomme ich die Fehlermeldung E2009 Inkompatible Typen: 'Methodenzeiger und reguläre Prozedur' . Wenn ich den Lösungsvorschlag von hier nutze, wird das Programm zwar kompiliert, es kommt aber kein Ereignis an

Es geht um folgenden Code(ausschnitt):
Delphi-Quellcode:
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.
Wie löst man das Problem?

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.
Angehängte Dateien
Dateityp: zip Small_DirMon.zip (5,1 KB, 7x aufgerufen)
Alex Winzer
  Mit Zitat antworten Zitat
Benutzerbild von DeddyH
DeddyH

Registriert seit: 17. Sep 2006
Ort: Barchfeld
27.265 Beiträge
 
Delphi 10.4 Sydney
 
#2

AW: Reguläre Prozedur in Methodenzeiger umwandeln

  Alt 24. Mai 2017, 15:58
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:
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;
Sollte so in etwa funktionieren.
Detlef
"Ich habe Angst vor dem Tag, an dem die Technologie unsere menschlichen Interaktionen übertrumpft. Die Welt wird eine Generation von Idioten bekommen." (Albert Einstein)
Dieser Tag ist längst gekommen
  Mit Zitat antworten Zitat
Namenloser

Registriert seit: 7. Jun 2006
Ort: Karlsruhe
3.724 Beiträge
 
FreePascal / Lazarus
 
#3

AW: Reguläre Prozedur in Methodenzeiger umwandeln

  Alt 24. Mai 2017, 16:00
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:
type
TFoobar = class
  procedure SayHello(Name: String);
end;

procedure TFoobar.SayHello(Name: String);
begin
  WriteLn("Hello, ", Name);
end;
wird intern zu

Delphi-Quellcode:
type
TFoobar = class
end;

procedure TFoobar_SayHello(Self: TFoobar, Name: String);
begin
  WriteLn("Hello, ", Name);
end;
Wenn du einfach castest, dann steht in den Parametern also nur Murks.
  Mit Zitat antworten Zitat
Schwedenbitter

Registriert seit: 22. Mär 2003
Ort: Finsterwalde
622 Beiträge
 
Turbo Delphi für Win32
 
#4

AW: Reguläre Prozedur in Methodenzeiger umwandeln

  Alt 24. Mai 2017, 22:22
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.
Alex Winzer
  Mit Zitat antworten Zitat
Benutzerbild von Stevie
Stevie

Registriert seit: 12. Aug 2003
Ort: Soest
3.824 Beiträge
 
Delphi 10.1 Berlin Enterprise
 
#5

AW: Reguläre Prozedur in Methodenzeiger umwandeln

  Alt 25. Mai 2017, 17:59
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).
Stefan
“Simplicity, carried to the extreme, becomes elegance.” Jon Franklin

Delphi Sorcery - DSharp - Spring4D - TestInsight
  Mit Zitat antworten Zitat
Benutzerbild von Zacherl
Zacherl

Registriert seit: 3. Sep 2004
4.629 Beiträge
 
Delphi 10.2 Tokyo Starter
 
#6

AW: Reguläre Prozedur in Methodenzeiger umwandeln

  Alt 26. Mai 2017, 13:39
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.
Probier statt
Delphi-Quellcode:
while Run do
begin
  Sleep();
end;
mal bitte
Delphi-Quellcode:
var
  Msg: TMsg;
..
begin
..
  while GetMessage(Msg, 0, 0, 0) do
  begin
    TranslateMessage(Msg);
    DispatchMessage(Msg);
  end;
Projekte:
- GitHub (Profil, zyantific)
- zYan Disassembler Engine ( Zydis Online, Zydis GitHub)
  Mit Zitat antworten Zitat
Themen-Optionen Thema durchsuchen
Thema durchsuchen:

Erweiterte Suche
Ansicht

Forumregeln

Es ist dir nicht erlaubt, neue Themen zu verfassen.
Es ist dir nicht erlaubt, auf Beiträge zu antworten.
Es ist dir nicht erlaubt, Anhänge hochzuladen.
Es ist dir nicht erlaubt, deine Beiträge zu bearbeiten.

BB-Code ist an.
Smileys sind an.
[IMG] Code ist an.
HTML-Code ist aus.
Trackbacks are an
Pingbacks are an
Refbacks are aus

Gehe zu:

Impressum · AGB · Datenschutz · Nach oben
Alle Zeitangaben in WEZ +2. Es ist jetzt 02:39 Uhr.
Powered by vBulletin® Copyright ©2000 - 2021, Jelsoft Enterprises Ltd.
LinkBacks Enabled by vBSEO © 2011, Crawlability, Inc.
Delphi-PRAXiS (c) 2002 - 2021 by Daniel R. Wolf