Newsgroup: it.comp.lang.delphi
Titolo: Evento OnPacket in DLL che non si attiva

Ciao a tutti,
il codice che riporto fa parte di una DLL con il protocollo di
comunicazione di una seriale, la connessione e l'invio dei dati viene
effettuata correttamente ma la ricezione non si attiva; nel senso che
non ho alcun errore nella compilazione ma dalle prove fatte non viene
mai intercettato l'evento del componente ApdDataPacket e quindi la
procedura assegnata non viene mail eseguita. Probabilmente ho sbagliato
qualcosa ma non so cosa, potete darmi una mano? O è tutto sbagliato?
:(
Grazie
Il codice è questo:
----------------------------------------------------------------------------------------------------------------------------------
type
  TPortCom = class(TObject)
    ApdDataPacket1: TApdDataPacket;
    ApdComPort1: TApdComPort;
  public
    constructor Create(AOwner: TComponent);
    destructor Destroy; override;
    procedure ApdDataPacket1Packet(Sender: TObject; Data: Pointer;
Size: Integer);
  end;
var
  PortCom       : TPortCom;
  ET               : EventTimer;
  Conn            : Boolean;
  Prova           : PChar;
constructor TPortCom.Create(AOwner: TComponent);
begin
  ApdComPort1 := TApdComPort.Create(nil);
  ApdDataPacket1 := TApdDataPacket.Create(nil);
end;
destructor TPortCom.Destroy;
begin
  ApdComPort1.Open := false;
  FreeAndNil(ApdComPort1);
  FreeAndNil(ApdDataPacket1);
  ApdComPort1.Destroy;
  ApdDataPacket1.Destroy;
end;
procedure TPortCom.ApdDataPacket1Packet(Sender: TObject; Data: Pointer;
Size: Integer);
begin
Prova := Data;
end;
Function DownloadPollingNEW(ADD: PChar; IDBOX: PChar): PChar; export;
StdCall;
 var
  Response    : String;
  VerifyXor   : Byte;
  I           : Integer;
begin
      Try
      //Invio il carattere EOT di chiusura per evitare trasmissioni
aperte precedentemente
      PortCom.ApdComPort1.PutString(chr($04));
      //Invio la stringa di Polling: [SOH][GID][DID][ENQ] che in
esadecimale diventa [01][41][?][05]
      PortCom.ApdComPort1.PutString(chr($01)+ADD+IDBOX+chr($05));
            PortCom.ApdDataPacket1.ComPort := PortCom.ApdComPort1;
            PortCom.ApdDataPacket1.StartCond := scString;
            PortCom.ApdDataPacket1.StartString := #2;
            PortCom.ApdDataPacket1.EndCond := [ecString];
            PortCom.ApdDataPacket1.EndString := #3+'?';
            PortCom.ApdDataPacket1.OnPacket :=
PortCom.ApdDataPacket1Packet; <---------- ASSEGNAZIONE EVENTO
      //Alloco memoria per contenere il valore di ritorno della
funzione da passare al software
      if Prova <> '' then
        Response := Prova
      else
        Response := 'Nessun dato';
      GetMem(Result,Length(Response));
      //Copio il valore di ritorno nella variabile che la funzione
ritorna
      Result := StrPCopy(Result, Response);
      //Result := PChar(Response);
      Except
      //Alloco memoria per contenere il valore di ritorno della
funzione da passare al software
      GetMem(Result,StrLen('ERROR'));
      //Copio il valore di ritorno nella variabile che la funzione
ritorna
      Result := StrPCopy(Result, 'ERROR');
      end;
end;
Procedure Connect(Baud: PChar; COM: PChar) export; StdCall;
var Creato: String;
begin
  PortCom := TPortCom.Create(nil);
  try
  //Configuro la porta seriale e la apro per iniziare le comunicazioni
    PortCom.ApdComPort1.ComNumber := StrToInt(COM);
    PortCom.ApdComPort1.Baud := StrToInt(Baud);
    PortCom.ApdComPort1.Parity := pNone;
    PortCom.ApdComPort1.DataBits := 8;
    PortCom.ApdComPort1.StopBits := 1;
    PortCom.ApdComPort1.InSize := 256;
    PortCom.ApdComPort1.Open := true;
    Conn := true;
  except
    FreeAndNil(PortCom.ApdComPort1);
  end;
end;
Procedure Disconnect() export; StdCall;
begin
  PortCom.ApdComPort1.open := false;
  FreeAndNil(PortCom.ApdComPort1);
  FreeAndNil(PortCom.ApdDataPacket1);
  Conn := false;
end;
----------------------------------------------------------------------------------------------------------------------------------

 end;
hai letto bene nella guida cosa fa FreeAndNil?
A.

No, nessun motivo preciso per l'assegnazione dell'evento prima
dell'utilizzo, cambia qualcosa?.
Non ho sottomano la guida di delphi ma FreeAndNil() non è la funzione
per liberare la memoria dell'oggetto e impostarne il valore a null?
Alberto Salvati ha scritto:


 > >   ApdComPort1.Destroy;
A.

Ok, correggerò le due parti di codice ma l'evento OnPacket non viene
comunque rilevato, perchè? Cosa c'è di sbagliato?
Alberto Salvati ha scritto:


sposta la pustring DOPO le assegnazioni.
Poi ho notato solo adesso alcuni errori madornali:
Procedure Connect(Baud: PChar; COM: PChar) export; StdCall;
var Creato: String;
begin
  PortCom := TPortCom.Create(nil);
  try
  //Configuro la porta seriale e la apro per iniziare le comunicazioni
    PortCom.ApdComPort1.ComNumber := StrToInt(COM);
    PortCom.ApdComPort1.Baud := StrToInt(Baud);
    PortCom.ApdComPort1.Parity := pNone;
    PortCom.ApdComPort1.DataBits := 8;
    PortCom.ApdComPort1.StopBits := 1;
    PortCom.ApdComPort1.InSize := 256;
    PortCom.ApdComPort1.Open := true;
    Conn := true;
  except
    FreeAndNil(PortCom.ApdComPort1);
  end;
end;
Prima di tutto, se viene alzata una eccezione, non la vderai mai.
La app non avra' nessun tipo di feedback per capire cosa non va nella
funzione connect.
Ergo, se un cliente ti chiama e ti dice che "non funziona" tu non hai
alcuna indicazione sul tipo di errore.
Poi, qui possono andare storte 3 cose, le 2 StrToInt e la connect.
Quindi, io la connect la farei cosi:
FUNCTION Connect(Baud: PChar; COM: PChar, ErrorMsg: pchar): INTEGER
export; StdCall;
var
  Creato: String;
  ComNumber: integer;
  BaudNumber: integer;
     function ForceInt(const AValue: string): integer;
     begin
          try
                Result := StrToInt(AValue);
          except
                Result := -999999;
          end;
    end;
begin
  ComNumber := ForceInt(COM);
  if ComNumber = -999999 then
  begin
    ErrorMsg := 'Invalid port number!';+ COM;
    Result := -100; // invalid port number!
    exit;
  end;
  BaudNumber := ForceInt(Baud);
  if BaudNumber = -999999 then
  begin
    ErrorMsg := 'Invalid baud!' + BAUD;
    Result := -200;
    exit;
  end;
  PortCom := TPortCom.Create(nil);
  try
     TRY
        //Configuro la porta seriale e la apro per iniziare le
comunicazioni
        PortCom.ApdComPort1.ComNumber := ComNuber;
    PortCom.ApdComPort1.Baud := BaudNumber;
    PortCom.ApdComPort1.Parity := pNone;
    PortCom.ApdComPort1.DataBits := 8;
    PortCom.ApdComPort1.StopBits := 1;
    PortCom.ApdComPort1.InSize := 256;
    PortCom.ApdComPort1.Open := true;
    Conn := true;
    RESULT := 0; // OK, CONNECTED!
  except
    ON E:EXCEPTION DO
    BEGIN
        RESULT := - 500; // FAIL OPEN COM PORT
        ERRORMSG := 'FAIL OPEN COM PORT:' + E.MESSAGE;
        FreeAndNil(PortCom.ApdComPort1);
    END
  END;
  end;
end;
In questo modo la app riceve un msg di errore che puo mostrare.
Il codice e' scritto di fretta e quindi di sicuro troverai qualche
cazzata, ma credo che la logica sia chiara.
A.

Allora, non ho modificato ancora il sorgente basandomi sui tuoi
suggerimenti, per ora ho solo inserito la callback nella procedura di
create.
Il resto dei consigli li sistemerò in seguito, ora mi preme capire
perchè l'evento non viene catturato, dato che ancora non lo fa e non
so perchè. A parte gli eventuali problemi di gestione degli errori ed
eccezioni, c'è qualcos'altro di sbagliato nella logica del mio codice?
Alberto Salvati ha scritto:
