Delphi-PRAXiS

Delphi-PRAXiS (https://www.delphipraxis.net/forum.php)
-   Object-Pascal / Delphi-Language (https://www.delphipraxis.net/32-object-pascal-delphi-language/)
-   -   Delphi Callbacks innerhalb einer Klasse (https://www.delphipraxis.net/35585-callbacks-innerhalb-einer-klasse.html)

Kanonier 9. Dez 2004 12:48


Callbacks innerhalb einer Klasse
 
Ich versuche gerade die Socket Classe von System.net in einer eigen Klasse für eine Server-Client-Anwendung zu implementieren. Das ganze soll asynchron ablaufen. Leider finde ich keine Möglichkeit einen Callback als Methode der Klasse zu implementieren.

hier mein Code
Delphi-Quellcode:
type TGalSocketServer = Class(TObject)
  private
   ServerSocket: Socket;
   Port: Integer;
   ActiveState: Boolean;
   localEndPoint: IPEndPoint;
   ipHostInfo: IPHostEntry;
   localipAddress: IPAddress;
   procedure AcceptCallBack(ar: IAsyncResult);
  public
   property active: Boolean read ActiveState;
   procedure open;
   procedure close;
   constructor create(pPort: Integer = 5024);
   destructor destroy;override;
end;

constructor TGalSocketServer.create(pPort: Integer = 5024);
begin
  inherited create;
  Port := pPort;
  //Ermitlung des Hostdaten
  ipHostInfo := Dns.Resolve(Dns.GetHostName);
  localipAddress := ipHostInfo.AddressList[0];
  localEndPoint := IPEndPoint.Create(localipAddress, Port);
  //Erstellung eines Sockets
  ServerSocket := Socket.Create(localEndPoint.AddressFamily,
                            SocketType.Stream,
                            ProtocolType.Tcp);
end;

destructor TGalSocketServer.Destroy;
begin
  ServerSocket.Free;
  localEndPoint.Free;
  ipHostInfo.Free;
  localipAddress.Free;
  inherited Destroy;
end;

procedure TGalSocketServer.open;
begin
  ServerSocket.Bind(localEndPoint);
  ServerSocket.Listen(100);
  ServerSocket.BeginAccept(AsyncCallback(TGalSocketServer.AcceptCallBack),
                           ServerSocket);
end;

procedure TGalSocketServer.close;
begin
  if not ActiveState then
    Exit;
  ServerSocket.Shutdown(SocketShutdown.Both);
  ServerSocket.Close;
end;

procedure TGalSocketServer.AcceptCallBack(ar: IAsyncResult);
var Listener, Handle: Socket;
begin
  Listener := Socket(ar.AsyncState);
  handle := Listener.EndAccept(ar);
  //Hier muss der Begin der abfrage von Daten vom Client rein
  handle.Shutdown(SocketShutdown.Both);
  handle.Close;
end;
Ich kriege es compiliert jedoch sobald ServerSocket.BeginAccept aufgerufen wird. Wird eine Ausnahme geworfen (Null reference).
Setze ich aber hier eine Funktion die nicht Member der klasse ist, so funktioniert es tadel los.

kennt einer sowas???

Luckie 9. Dez 2004 12:55

Re: Callbacks innerhalb einer Klasse
 
Das liegt daran, dass Methoden immer noch den unsichtbaren self-Parameter mit über geben bekommen. somit stimmt dann deine Parameterliste nicht mehr.

Kanonier 9. Dez 2004 13:26

Re: Callbacks innerhalb einer Klasse
 
Dann dürfte es aber nicht zu kompilieren sein.
Die Ausnahme passiert erst zu Laufzeit.

Luckie 9. Dez 2004 13:28

Re: Callbacks innerhalb einer Klasse
 
Wie so? Ist doch kein Syntaxfehler.

Kanonier 9. Dez 2004 14:43

Re: Callbacks innerhalb einer Klasse
 
Ich habs gelösst. Ich weise erst bei der Konstruktione einen Callback zu dann geht es.

Delphi-Quellcode:
type TGalSocketServer = Class(TObject)
type OnCallBack = procedure of object;
  private
   //Definition aller Delagaten
   MyAcceptDelegate: AsyncCallback;
   MyReadDataDelegate: AsyncCallback;
   ServerSocket: Socket;
   Port: Integer;
   ActiveState: Boolean;
   localEndPoint: IPEndPoint;
   ipHostInfo: IPHostEntry;
   localipAddress: IPAddress;
   procedure AcceptCallBack(ar: IAsyncResult);
  public
   OnConnect: OnCallBack;
   property active: Boolean read ActiveState;
   property OnClientConnect: OnCallBack write OnConnect;
   procedure open;
   procedure close;
   constructor create(pPort: Integer = 5024);
   destructor destroy; override;
end;

constructor TGalSocketServer.create(pPort: Integer = 5024);
begin
  inherited create;
  Port := pPort;
  //Ermitlung des Hostdaten
  ipHostInfo := Dns.Resolve(Dns.GetHostName);
  localipAddress := ipHostInfo.AddressList[0];
  localEndPoint := IPEndPoint.Create(localipAddress, Port);
  //Erstellung eines Sockets
  ServerSocket := Socket.Create(localEndPoint.AddressFamily,
                            SocketType.Stream,
                            ProtocolType.Tcp);
  //initialiesierung aller Delegaten
  MyAcceptDelegate := Self.AcceptCallBack;
  MyReadDataDelegate := Nil;
  OnConnect := Nil;
end;
{konstruktor}
destructor TGalSocketServer.Destroy;
begin
  ServerSocket.Free;
  localEndPoint.Free;
  ipHostInfo.Free;
  localipAddress.Free;
  inherited Destroy;
end;

{Mit dieser prozedur wird der Sever gestartet und der Port überwacht}
procedure TGalSocketServer.open;
begin
  ServerSocket.Bind(localEndPoint);
  ServerSocket.Listen(100);
  ServerSocket.BeginAccept(Self.AcceptCallBack,
                           ServerSocket);
end;

procedure TGalSocketServer.close;
begin
  if not ActiveState then
    Exit;
  ServerSocket.Shutdown(SocketShutdown.Both);
  ServerSocket.Close;
end;

procedure TGalSocketServer.AcceptCallBack(ar: IAsyncResult);
var Listener, Handle: Socket;
begin
  Listener := Socket(ar.AsyncState);
  handle := Listener.EndAccept(ar);
  if Assigned(OnConnect) then
    OnConnect;
  //Hier muss der Begin der abfrage von Daten vom Client rein
  handle.Shutdown(SocketShutdown.Both);
  handle.Close;
end;


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