Delphi-PRAXiS

Delphi-PRAXiS (https://www.delphipraxis.net/forum.php)
-   Programmieren allgemein (https://www.delphipraxis.net/40-programmieren-allgemein/)
-   -   Delphi idUDPServer - Fehler bei Definition von OnUdpRead (https://www.delphipraxis.net/188225-idudpserver-fehler-bei-definition-von-onudpread.html)

TERWI 11. Feb 2016 13:57

idUDPServer - Fehler bei Definition von OnUdpRead
 
Weil unter Netzwerke irgendwie keine Lösung kommt, poste ich das hier in dieser Abteilung noch mal, weil es auch nicht unbedingt Netzwerktypisch ist
Zur Info vorweg: Delphi 7 mit Indy 10_5339 unter XP.

Zum testen von WebServices hatte ich mir zunächst eine einfache Form gebastelt, auf der ich u.a. je eine TIdIPMCastClient-, TIdIPMCastServer- TIdUDPServer- und eine TTimer-Komponente gepackt habe.
Die jeweiligen Ereignisprozeduren wurden jeweils mit Doppelklick im Objektinspektor erzeugt.

Nach kleinen anfänglichen Problemchen lief das Tool bereits nach kurzer Zeit recht ordentlich und da ich dazu eigentlich keine Form brauche, wollte ich die Funktionen zur Wiederverwendung in eine Klasse packen.
Also eine Klasse angelegt und Stück für Stück die einzelnen Komponenten eingetragen und proceduren übertragen.
So weit so gut - lässt sich problemlos kompilieren. Der Timer timed, die Multicast-Komp castet auch fleißig rein und raus ...

Nur der UDP-Server macht nachhaltig Zicken ! Beim zuweisen der Ereignissprozedur erscheint der Fehler:
"Incompatible types: Parameter lists differ"
Wieso das denn ? ich habe nichts an der Prozedurdeklaration geändert ! Der Rest tuts doch auch ...

Nach einiger Sucherei im Netz fand ich Tips, dass der Compiler ggf. den Typ TidBytes nicht versteht und man statt dessen ein array of byte nehmen sollte.
Das war es aber auch nicht.

Weitere Sucherei brachte mich auf diese Seite, wo exakt mein Prob beschrieben wurde:
http://www.delphigroups.info/2/11/215650.html
Ich habe diese "Krücke" mit TMethod mal ausprobiert - das sieht dann hier allerdings so aus
Delphi-Quellcode:
  // TWSDiscovery ist der Klassen-Name
  udpSrv_Send := TIdUDPServer.Create(nil);
  FMethod.Data := udpSrv_Send;                     // !!!!
  FMethod.Code := @TWSDiscovery.onUPDSrvRead;      // !!!!
  with udpSrv_Send do begin                        
    Active              := false;
    OnUDPRead           := TUDPReadEvent(FMethod); // !!!!
//    OnUDPRead           := onUPDSrvRead;         // FUNKTIONIERT NICHT
    Bindings.DefaultPort := FRcvPort + 1;
    DefaultPort         := FRcvPort + 1;
    BufferSize          := 8192;
    ThreadedEvent       := true;
    BroadcastEnabled    := true;
    Active              := True;
  end;
Dieses "Konstrukt" lässt sich nun zumindest fehlerfrei kompilieren.
Ich habe das zunächst der Einfachheit halber in der Art "gemonitort", als das ich die Unit meiner Hauptform unter IMPLEMENTATION mit USES eingetragen habe, um somit schnell und einfach was in ein MEMO zu schreiben.
Siehe folgender Code mit Hinweis "-> 1)"
Delphi-Quellcode:
// interface
//   uses {allerlei}
// ...
//   type TWSDiscovery = Class ....
// ...
//   var WSD : TWSDiscovery;
// ...
procedure TWSDiscovery.onUPDSrvRead(AThread : TIdUDPListenerThread;
                                    AData   : TidBytes; ABinding : TIdSocketHandle);
begin
  Form1.Memo1.Lines.Add(BytesToString(AData)); // -> 1) DAS FUNKTIONIERT
  Add2Memo(BytesToString(AData));              // -> 2) DAS FUNKTIONIERT NICHT
  wsd.Add2Memo(BytesToString(AData));          // -> 3) DAS FUNKTIONIERT AUCH
end;
Wäre ja nun alles prima, gäbe es da nicht immer dieses leidige ABER....
Damit das ganze vielseitig bleibt, habe ich eine CallBack-Funktion [TWSDiscovery.Add2Memo(s : string)] zum rufenden Programm eingebaut. Das funzt tadellos bei MCast und dem Timer - nur beim UDP-Server eben nicht.
Gemeint ist hier "-> 2).
Es tut sich gar nichts - keine Ahnung wo die Daten hin verschwinden.

Irgendwann habe ich dann einfach mal wie bei "-> 3)" wsd. davorgeschrieben .... das geht dann wieder.
Das erweckt hier den Eindruck, das der UDP-Server und seine OnRead-Prozedur gar nicht zur Klasse gehört - ist aber definitv darin deklariert und instanziert.

Kann das bitte mal jemand erklären - und noch besser: lösen !?

TERWI 11. Feb 2016 19:12

AW: idUDPServer - Fehler bei Definition von OnUdpRead
 
Hab's mit noch mal lesen, suchen und überlegen durch Zufall nun doch selbst rausgefunden !:hello:

Das einzig wichtige Zauberwort bzw. Definition EINER Variablen lautet:
Delphi-Quellcode:
CONST]


Da ja nicht nur hier reichlich Mitleser sind, aber (kaum) (k)einer was fragt oder dazu sagt, gebe ich die Antwort erst ...
... wenn einer fragt: ... und wo (genau) ? oder so ...

Nu lüppt dat hier endlich as dat mutt! :witch:

(Wer es mir vorher sagen kann, wo genau das CONST stehen muss, bekommt ein .... mal sehen, was im Angebot ist)

Sir Rufo 11. Feb 2016 19:24

AW: idUDPServer - Fehler bei Definition von OnUdpRead
 
  1. Delphi-Quellcode:
    TIdUDPServer
    Komponente auf die Form klatschen
  2. Im OI ein Doppelklick auf
    Delphi-Quellcode:
    OnUDPRead
  3. Augen auf:
    Delphi-Quellcode:
    procedure TForm1.IdUDPServer1UDPRead(AThread: TIdUDPListenerThread;
      const AData: TIdBytes; ABinding: TIdSocketHandle);
    begin

    end;
Alternative, wenn der Doppelklick mal nicht will:
  1. Per STRG-Maus-Klick auf
    Delphi-Quellcode:
    TIdUDPServer
    im Editor
  2. Dann kommt man zu der Stelle, wo das hier steht
    Delphi-Quellcode:
      TUDPReadEvent = procedure(AThread: TIdUDPListenerThread; const AData: TIdBytes; ABinding: TIdSocketHandle) of object;

      TIdUDPServer = class(TIdUDPBase)
      protected
        FBindings: TIdSocketHandles;
        FCurrentBinding: TIdSocketHandle;
        FListenerThreads: TIdUDPListenerThreadList;
      ...
  3. Da steht groß und breit
    Delphi-Quellcode:
    const
    vor
    Delphi-Quellcode:
    AData: TIdBytes

Wer jetzt was bekommt? Du eine Maus oder eine Lesebrille oder ... :mrgreen:

TERWI 11. Feb 2016 20:58

AW: idUDPServer - Fehler bei Definition von OnUdpRead
 
Sir Rufo bekommt dann den Delphi-3fach-Bingo-Zettel für die nächsten 3 Wochen aboniert !

Aber mal im Ernst:
Das mit der Doppel-Click-Sache habe ich logo in der Form ursprünglich genauso gemacht. Siehe Postings.
Da war NIX DAS WAS mit const davor !
Ich habe 1:1 kopiert ....

Von wegen 'Augen auf' - da war defitiniv und absolut kein CONST vor ADATA !!
Ich habe die ganze Prozedur so wie sie in der Form erzeugt wurde 1:1 mit Copy/Paste übernommen !!

Die Quizfrage stellt sich hier ja: Warum dudelte das in der Form (AUCH OHNE CONST !) und in der Klasse nicht ?
Das war ja eben drum die Frage ....

COMPILER-Fehler/Problem ?
Aufgemerkt: Ich kaspere hier noch OLD-Fashioned mit DELPHI 7 auf XP mit Indy 10_5339 !
... möglicherweise machen neuere Compiler keine Zicken ... ?
... und bei Indy hat sich ggf. wieder was geändert ?
Egal - ich bin happy ...... bis zum nächsten Prob.

Auf jeden Fall den Mega-Dank an Sir Rufo, der zufällig (schon mal ?) das gleiche Prob erkannt hat. :angel2: :mrgreen:

Sir Rufo 11. Feb 2016 21:45

AW: idUDPServer - Fehler bei Definition von OnUdpRead
 
Das war mal (früher, damals) ohne
Delphi-Quellcode:
const
(s. https://github.com/skelter/Indy/blob...erver.pas#L120 - irgendeine Version aus 2011)

Da wirst du wohl bei deinem Update (Delphi 7 hat ja nicht von Haus aus Indy 10) irgendetwas übersehen haben und die Form-Klatsch-Komponente ist noch eine ältere Version, als die, die du da nackig verwendest.

Trotz allem hätte ein STRG-Klick auf den Klassen-Namen bzw. auf den Eigenschaftsnamen direkt dort hin geleitet, wo du die Signatur der Event-Methode erfahren kannst.

Ich mache das schon immer reflexartig, wenn so ein Fehler aufpoppt :stupid:

TERWI 17. Feb 2016 15:02

AW: idUDPServer - Fehler bei Definition von OnUdpRead
 
jajajaja .... du und die anderen haben ja Recht. :roll:
Hier der Verweis auf mein MEA CULPA:
http://www.delphipraxis.net/1330657-post17.html


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