Visualizzazione dei risultati da 1 a 10 su 10
  1. #1
    Utente di HTML.it L'avatar di colde
    Registrato dal
    Feb 2001
    Messaggi
    1,802

    Creazione oggetti e assegnazione eventi

    Ciao Alka,
    finalmente sono riuscito a creare i miei oggetti nella DLL direttamente da codice, ti inserisco comunque il sorgente in modo che tu possa controllarlo e dirmi se ci sono errori di concetto. Ti assicuro che tutto il codice inserito non è frutto di immaginazione o tentativi come facevo fino a poco tempo fa, oggi ho avuto l'illuminazione e quello che ho scritto l'ho capito. Il problema principale ora è capire come gestire gli eventi, questo ancora mi è ignoto anche se un'idea ce l'avrei, in più quando chiudo il form dopo aver richiamato la funzione Connect() e DownloadPollingNEW() (e nient'altro) mi da errore di access violation. Puoi fare luce nel buio della mia mente?

    Il codice di base della DLL è questo:
    codice:
    type
      TPortCom = class //creo una nuova classe
        ApdDataPacket1: TApdDataPacket; //assegno alla classe l'oggetto figlio
        ApdComPort1: TApdComPort; //assegno alla classe l'oggetto figlio
      public
        constructor Create(AOwner: TComponent); //assegno il costruttore
        destructor Destroy; override; //assegno il distruttore
        procedure ApdDataPacket1StringPacket(Sender: TObject; Data: string); //assegno l'evento che però non funziona
      end;
    
    constructor TPortCom.Create(AOwner: TComponent); //procedura richiamata dal costruttore al comando TPortCom.Create()
    begin
      ApdComPort1 := TApdComPort.Create(nil); //creo l'oggetto ApdComPort1
      ApdDataPacket1 := TApdDataPacket.Create(nil); //creo l'oggetto ApdDataPacket1
    end;
    
    destructor TPortCom.Destroy; //procedura richiamata per la distruzione della classe
    begin
      FreeAndNil(PortCom.ApdComPort1); //libero la memoria di ApdComPort1
      FreeAndNil(PortCom.ApdDataPacket1); //libero la memoria di ApdDataPacket1
      ApdComPort1.Destroy; //distruggo l'oggetto
      ApdDataPacket1.Destroy; //distruggo l'oggetto
    end;
    
    procedure TPortCom.ApdDataPacket1StringPacket(Sender: TObject; Data: string);
    begin
    Prova := Trim(Data);
    end;
    
    Function DownloadPollingNEW(ADD: PChar; IDBOX: PChar): PChar; export; StdCall;
     var
      Response    : String;
      VerifyXor     : Byte;
      I                : Integer;
    begin
          FreeAndNil(Response);
          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+'?';
          //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; //Procedura richiamata dal software esterno
    begin
      PortCom := TPortCom.Create(nil); //Creo la classe e i suoi oggetti
      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;
    Grazie
    www.beppegrillo.it
    Il blog di Beppe!!

  2. #2
    Utente di HTML.it L'avatar di colde
    Registrato dal
    Feb 2001
    Messaggi
    1,802
    Dunque, mi ero dimenticato di inserire il riferimento all'evento di ApdDataPacket.OnPacket così ho inserito:

    PortCom.ApdDataPacket1.OnPacket := PortCom.ApdDataPacket1Packet;

    Ora la funzione DownloadPollingNEW() risulta così:

    Function DownloadPollingNEW(ADD: PChar; IDBOX: PChar): PChar; export; StdCall;
    var
    Response : String;
    VerifyXor : Byte;
    I : Integer;
    begin
    FreeAndNil(Response);
    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+c hr($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; <--- 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;


    Però non lo rileva comunque, mi sai dire dove sbaglio? Mi sembra che sia corretto ma evidentemente c'è qualcosa di sbagliato nella dichiarazione del Type, credo che dipenda da quello.
    Grazie
    www.beppegrillo.it
    Il blog di Beppe!!

  3. #3
    Moderatore di Programmazione L'avatar di alka
    Registrato dal
    Oct 2001
    residenza
    Reggio Emilia
    Messaggi
    24,301
    Non è chiaro cosa sia PortCom... :master:
    MARCO BREVEGLIERI
    Software and Web Developer, Teacher and Consultant

    Home | Blog | Delphi Podcast | Twitch | Altro...

  4. #4
    Utente di HTML.it L'avatar di colde
    Registrato dal
    Feb 2001
    Messaggi
    1,802
    Perchè? E' la classe principale che mi serve per poter utilizzare i due componenti ApdComPort e ApdDataPacket. E' sbagliato? Vuoi dire che non ho capito una fava e mi sono montato solo castelli di sabbia?
    www.beppegrillo.it
    Il blog di Beppe!!

  5. #5
    Moderatore di Programmazione L'avatar di alka
    Registrato dal
    Oct 2001
    residenza
    Reggio Emilia
    Messaggi
    24,301
    Originariamente inviato da colde
    Perchè? E' la classe principale che mi serve per poter utilizzare i due componenti ApdComPort e ApdDataPacket. E' sbagliato? Vuoi dire che non ho capito una fava e mi sono montato solo castelli di sabbia?
    No, non ricordavo la presenza del codice sopra. Ma quel codice (quello del primo messaggio) è ancora quello attuale? :master:
    MARCO BREVEGLIERI
    Software and Web Developer, Teacher and Consultant

    Home | Blog | Delphi Podcast | Twitch | Altro...

  6. #6
    Utente di HTML.it L'avatar di colde
    Registrato dal
    Feb 2001
    Messaggi
    1,802
    Non ho ben capito la tua domanda ma ti riposto il codice per intero con l'aggiunta dell'assegnazione dell'evento alla procedura.

    codice:
    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
          FreeAndNil(Response);
          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;
          //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;
    www.beppegrillo.it
    Il blog di Beppe!!

  7. #7
    Moderatore di Programmazione L'avatar di alka
    Registrato dal
    Oct 2001
    residenza
    Reggio Emilia
    Messaggi
    24,301
    codice:
    var
      Response    : String;
    
     ...
          FreeAndNil(Response);
    VVoVe:
    MARCO BREVEGLIERI
    Software and Web Developer, Teacher and Consultant

    Home | Blog | Delphi Podcast | Twitch | Altro...

  8. #8
    Utente di HTML.it L'avatar di colde
    Registrato dal
    Feb 2001
    Messaggi
    1,802
    Ops non mi sono accorto, era un rimasuglio del vecchio codice per tentare di capire perchè si bloccava a metà la ricezione dei dati da seriale. Ho pensato che magari rimaneva del testo per qualche errore e la lunghezza dei dati superava la lunghezza massima della stringa ma non era così. Non sono riuscito a capire il motivo di quel comportamento, era per questo che al secondo ciclo di download dei dati si impiantava e mi dava access violation; ad un certo punto dopo una trentina di caratteri scaricati mi diceva che il processo non era più valido. Forse era la procedura di scarico dati che utilizzavo che non era ottimale per le mie necessità ed è per quel motivo che ora sto provando a usare il datapacket e non il getchar.
    Va bhe ora ho eliminato quella parte ma comunque non mi assegna l'evento alla procedura che gli ho indicato. Il problema rimane. L'invio della richiesta da DLL a seriale sono sicuro che funziona perchè il PC vede la richiesta e in teoria mi manda la risposta con i dati richiesti ma non si attiva l'evento per il recupero.
    www.beppegrillo.it
    Il blog di Beppe!!

  9. #9
    Utente di HTML.it L'avatar di colde
    Registrato dal
    Feb 2001
    Messaggi
    1,802
    UP!! Niente da fare, l'evento non viene associato.

    codice:
    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;
          //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;
    www.beppegrillo.it
    Il blog di Beppe!!

  10. #10
    Utente di HTML.it L'avatar di colde
    Registrato dal
    Feb 2001
    Messaggi
    1,802
    UP!!
    www.beppegrillo.it
    Il blog di Beppe!!

Permessi di invio

  • Non puoi inserire discussioni
  • Non puoi inserire repliche
  • Non puoi inserire allegati
  • Non puoi modificare i tuoi messaggi
  •  
Powered by vBulletin® Version 4.2.1
Copyright © 2024 vBulletin Solutions, Inc. All rights reserved.