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

    Procedure e Function: chiarimenti

    Ciao Alka,
    avrei bisogno di alcuni chiarimenti:
    premesso che una procedura differisce da una funzione poichè quest'ultima può accettare e restituire un valore mentre la procedura accetta solo valori in ingresso,
    mettiamo il caso di avere una funzione che accetta e restituisce parametri e che questa funzione richiami una procedura "TTimer.OnEvent". Questa procedura serve per far partire il timer che crea una stringa in modo tale che a ogni secondo viene aggiunto un carattere alla stringa stessa; è possibile passare alla funzione la stringa completa creata a fine procedura?
    Spero di essere stato chiaro.

    Grazie mille
    www.beppegrillo.it
    Il blog di Beppe!!

  2. #2
    Moderatore di Programmazione L'avatar di alka
    Registrato dal
    Oct 2001
    residenza
    Reggio Emilia
    Messaggi
    24,322

    Re: Procedure e Function: chiarimenti

    Originariamente inviato da colde
    premesso che una procedura differisce da una funzione poichè quest'ultima può accettare e restituire un valore mentre la procedura accetta solo valori in ingresso
    Sia le procedure che le funzioni accettano valori in ingresso (detti "parametri" o "argomenti"); l'unica differenza è che le funzioni restituiscono un valore di ritorno, le procedure no.

    Originariamente inviato da colde
    mettiamo il caso di avere una funzione che accetta e restituisce parametri e che questa funzione richiami una procedura "TTimer.OnEvent". Questa procedura serve per far partire il timer che crea una stringa in modo tale che a ogni secondo viene aggiunto un carattere alla stringa stessa; è possibile passare alla funzione la stringa completa creata a fine procedura?
    Spero di essere stato chiaro.
    Qualsiasi parametro passato ad una funzione o ad una procedura può essere modificato; generalmente, quando si modifica un parametro all'interno di una routine e si effettua il ritorno da questa, le modifiche apportate al valore vanno perse.

    Dichiarando il parametro facendolo precedere dalla parola chiave var, qualsiasi modifica ad esso all'interno della routine viene mantenuta anche al ritorno.

    Fa parte dell'ABC del linguaggio Pascal. E' la tematica del passaggio di parametri per valore o per riferimento, per cui trovi fiumi di documentazione ovunque, ivi compresa la documentazione di Delphi sul linguaggio.

    Ciao!
    MARCO BREVEGLIERI
    Software and Web Developer, Teacher and Consultant

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

  3. #3
    Utente di HTML.it L'avatar di colde
    Registrato dal
    Feb 2001
    Messaggi
    1,802

    Re: Re: Procedure e Function: chiarimenti

    Originariamente inviato da alka
    Dichiarando il parametro facendolo precedere dalla parola chiave var, qualsiasi modifica ad esso all'interno della routine viene mantenuta anche al ritorno.
    Perdonami ma non mi è chiaro cosa intendi.

    Ti faccio il mio esempio:
    da una function richiamo la procedura che ad ogni secondo mi modifica la stringa; questa stringa viene salvata in una variabile pubblica in modo da poterla riutilizzare da tutte le funzioni e procedure esistenti. Ora, ho due possibilità:
    - ripassare la variabile dalla procedura alla funzione in modo che quest'ultima la restituisca all'applicazione come parametro di ritorno;
    - passare la variabile rirettamente dalla procedura all'applicazione;

    La seconda soluzione mi pare un po ardua, sempre che sia possibile, così ho optato per la prima. La procedura crea la stringa, la metto in una variabile pubblica e la assegno a Result della funzione per poi stamparla a video. Per qualche motivo non va.
    Essendo la procedura richiamata da una funzione, quando la routine della procedura termina, la funzione riprende dai comandi successivi alla chiamata oppure termina il processo punto e basta?

    Dato il seguente codice per attivare il timer:

    var
    response: string;

    function prova(): string;
    begin
    timer.interval := 3000;
    timer.OnTimer := avviatimer; // all'evento Ontimer avvio la procedura 'avviatimer'
    timer.enable := true; // abilito il timer scatenando l'evento Ontimer
    Result := response; //recupero il valore creato dalla procedura e lo passo all'applicazione
    end;

    procedure avviatimer(Sender: TObject);
    begin
    Response := response+'OK ';
    end;


    L'esempio in teoria dovrebbe dare come ritorno una stringa di questo tipo 'OK OK OK ' invece non stampa nulla quindi il dubbio è che terminata la procedura, la funzione chiamante non riprende la sua esecuzione.
    www.beppegrillo.it
    Il blog di Beppe!!

  4. #4
    Moderatore di Programmazione L'avatar di alka
    Registrato dal
    Oct 2001
    residenza
    Reggio Emilia
    Messaggi
    24,322

    Re: Re: Re: Procedure e Function: chiarimenti

    Originariamente inviato da colde
    L'esempio in teoria dovrebbe dare come ritorno una stringa di questo tipo 'OK OK OK ' invece non stampa nulla quindi il dubbio è che terminata la procedura, la funzione chiamante non riprende la sua esecuzione.
    Assolutamente no, in quanto tu attivi presumibilmente un TTimer che esegue operazioni periodicamente (Windows si preoccupa di inviare un messaggio all'applicazione quando è il momento, per far eseguire l'evento associato al timer), ma la funzione ritorna subito, restituendo quindi il valore corrente della variabile response che è vuoto; l'evento di risposta al timer viene eseguito periodicamente e successivamente (3 secondi dopo).
    MARCO BREVEGLIERI
    Software and Web Developer, Teacher and Consultant

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

  5. #5
    Utente di HTML.it L'avatar di colde
    Registrato dal
    Feb 2001
    Messaggi
    1,802
    Ok, credo di aver capito. Solo un'ultima cosa: se avvio una funzione da una procedura, la funzione restituisce il valore alla procedura che l'ha richiamata? Oppure il result di ritorno si riferisce sempre all'applicazione che ha generato la chiamata iniziale?

    Sempre facendo riferimento all'esempio di prima: da un'applicazione parte la chiamata a una funzione presente nella DLL che restituisce all'applicazione chiamante la stringa 'Prima funzione OK', abilita il timer e all'evento OnTimer richiama la procedura assegnata. Questa procedura richiama a sua volta un'altra funzione in modo che a ogni secondo venga eseguito il codice al suo interno. Questa funzione restituisce una stringa, dove va questa stringa? All'applicazione iniziale o alla procedura avviata all'evento OnTimer?
    www.beppegrillo.it
    Il blog di Beppe!!

  6. #6
    Moderatore di Programmazione L'avatar di alka
    Registrato dal
    Oct 2001
    residenza
    Reggio Emilia
    Messaggi
    24,322
    Originariamente inviato da colde
    Ok, credo di aver capito. Solo un'ultima cosa: se avvio una funzione da una procedura, la funzione restituisce il valore alla procedura che l'ha richiamata? Oppure il result di ritorno si riferisce sempre all'applicazione che ha generato la chiamata iniziale?

    Sempre facendo riferimento all'esempio di prima: da un'applicazione parte la chiamata a una funzione presente nella DLL che restituisce all'applicazione chiamante la stringa 'Prima funzione OK', abilita il timer e all'evento OnTimer richiama la procedura assegnata. Questa procedura richiama a sua volta un'altra funzione in modo che a ogni secondo venga eseguito il codice al suo interno. Questa funzione restituisce una stringa, dove va questa stringa? All'applicazione iniziale o alla procedura avviata all'evento OnTimer?
    C'è un po' di confusione, più che altro non capisco il ruolo degli eventi nel contesto.

    Mi spiego.

    Una funzione ha un valore di ritorno. Quando una funzione viene richiamata, è possibile assegnare il suo valore di ritorno ad una variabile.

    Un esempio per intenderci con la funzione StrToInt:

    codice:
    MyInteger := StrToInt(MyString);
    Il valore restituito dalla funzione viene quindi memorizzato in una variabile; ovunque si trovi questa variabile, non ha importanza, e la visibilità del valore e la durata dipenderanno dal valore e dalla durata della variabile stessa.

    Che questa variabile si trovi in un metodo, in una procedura, in un'altra funzione, non ha alcuna importanza.
    MARCO BREVEGLIERI
    Software and Web Developer, Teacher and Consultant

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

  7. #7
    Utente di HTML.it L'avatar di colde
    Registrato dal
    Feb 2001
    Messaggi
    1,802
    Il mio problema è che vorrei assegnare al risultato di una funzione la procedura OnTimer ma non so che valore passare.

    type
    TimerHandler = class(TObject)
    procedure OnTimer(Sender: TObject);
    end;


    {$R *.res}
    var
    aTH : TimerHandler;
    ApdComPort1 : TApdComPort;
    Timer : TTimer;
    Response : string;


    function prova(): string;
    begin
    aTH := TimerHandler.Create;
    Timer := TTimer.Create(nil);
    Timer.interval := 3000;
    Timer.OnTimer := aTH.OnTimer; // all'evento Ontimer avvio la procedura 'OnTimer'
    Timer.enable := true; // abilito il timer scatenando l'evento Ontimer
    Result := OnTimer(COSA METTO QUI?) //voglio visualizzare 'OK' creato in OnTimer
    end;

    procedure TimerHandler.OnTimer(Sender: TObject);
    begin
    Response := 'OK ';
    end;


    E' corretto il codice?
    www.beppegrillo.it
    Il blog di Beppe!!

  8. #8
    Moderatore di Programmazione L'avatar di alka
    Registrato dal
    Oct 2001
    residenza
    Reggio Emilia
    Messaggi
    24,322
    Originariamente inviato da colde
    Il mio problema è che vorrei assegnare al risultato di una funzione la procedura OnTimer ma non so che valore passare.
    E' assodato che la procedura non restituisce alcun valore.

    A parte questo fattore, non si capisce cosa devi fare.

    La funzione ritorna subito, mentre l'evento OnTimer viene richiamato periodicamente, non si sa fino a che punto (dato che il timer non viene disabilitato) accodando stringhe alla response, ma la funzione ha già restituito il valore da un pezzo.

    Non è chiaro nemmeno l'utilità del timer, che accoda un "OK" ad una stringa per un tempo indeterminato.
    MARCO BREVEGLIERI
    Software and Web Developer, Teacher and Consultant

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

  9. #9
    Utente di HTML.it L'avatar di colde
    Registrato dal
    Feb 2001
    Messaggi
    1,802
    il codice scritto non ha alcuna utilità, era un semplice esempio per permettermi di capire cosa diavolo devo fare per richiamare un timer da DLL che controlli la risposta di una porta COM da restituire all'applicazione.

    Spiego brevemente cosa devo fare:
    lo scopo è creare una DLL con il protollo di comunicazione di un apparecchio (chiamiamolo box) utilizzando la porta COM. Cosa importantissima, la DLL deve essere utilizzabile da qualsiasi linguaggio, non solo delphi, e non deve comprendere alcuna form ma solo funzioni e procedure. Attualmente ho creato la funzione che apre la connessione e invia la prima stringa di dati al box; una volta ricevuti, il box mi risponde con un'altra stringa di dati. La risposta del box può avvenire anche dopo due secondi quindi devo implementare un timer che verifichi la risposta ogni secondo o due.

    Ora ho creato la prima funzione (che a questo punto cambierò come procedura, tanto non può darmi nessun messaggio utile di ritorno) che si connette al box:

    function Polling(DID: Char): String; export; StdCall;
    var
    I: integer;
    begin
    ApdComPort1 := TApdComPort.Create(nil);
    try
    ApdComPort1.ComNumber := 1;
    ApdComPort1.Baud := 9600;
    ApdComPort1.Parity := pNone;
    ApdComPort1.DataBits := 8;
    ApdComPort1.StopBits := 1;
    ApdComPort1.BufferFull := 0;
    ApdComPort1.BufferResume := 0;
    ApdComPort1.Open := true;
    if ApdComPort1.Open then
    begin
    ApdComPort1.PutString(chr($04));
    ApdComPort1.PutString(chr($01)+chr($41)+chr($31)+c hr($05));
    Result := 'Polling OK.'
    //ApdComPort1.DonePort;
    end
    else Result := 'ERROR: -- COM Port Close --';
    finally
    //ApdComPort1.Free;
    end;
    end;

    la chiusura della connessione e la distruzione di ApdComPort1 è volutamente bypassato, capirai dopo perchè.

    La funzione che verifica l'esistenza dei risultati è:

    function Prova(): String; export; StdCall;
    var I : integer;
    begin
    if ApdComPort1.Open then
    begin
    if ApdComPort1.CharReady then
    begin
    while ApdComPort1.CharReady do
    begin
    Result := Result+ApdComPort1.GetChar;
    end;
    Result := Result;
    end
    else Result := 'No data received.';
    end
    else Result := 'ERROR: -- COM Port Close --';
    end;

    Ora per testare il codice ho creato un form a parte con due bottoni, uno per connettersi e richiamare la funzione Polling(), mentre l'altro per verificare l'eventuale risposta del box. Il tutto funziona, prima mi connetto e poi recupero i valori (ecco perchè non chiudo la connessione e non distruggo ApdComPort1) ma per gestire il tutto in modo automatico con un timer? Come posso fare? Anche il codice per reperire i dati di ritorno del box sono un pagliativo, visto che con tutta la mia buona volontà non sono riuscito a richiamare la procedura assegnata all'evento OnTriggerAvail del componente stesso e oltre a questo, essendo una procedura non posso inviare la risposta all'applicazione visuale.
    www.beppegrillo.it
    Il blog di Beppe!!

  10. #10
    Moderatore di Programmazione L'avatar di alka
    Registrato dal
    Oct 2001
    residenza
    Reggio Emilia
    Messaggi
    24,322
    Brevemente, se la DLL deve essere utilizzabile con altri linguaggi, è meglio limitarsi all'uso di tipi standard Windows, evitando quelli specifici di Delphi come le classi e le stringhe (string), ovviamente in riferimento alla parte "pubblica", cioè a quello che si vede all'esterno (i parametri e i valori di ritorno delle funzioni), mentre internamente (nell'implementazione) puoi usare ciò che vuoi. Non usare ShareMem.

    Sul problema specifico in se, non puoi usare un Timer. Devi verificare la presenza di metodi (vedi la documentazione) che rimanga in attesa, una volta impartito il comando, di ricevere dati, oppure effettuare un ciclo fino a quando non hai ottenuto la risposta voluta.

    Non puoi restituire immediatamente un valore se questo valore si forma progressivamente nel tempo, dopo che la funzione è già ritornata: o la funzione aspetta di ricevere tutti i dati necessari, o restituisce quelli che ha in quel momento e va richiamata più volte dall'applicazione che fa uso della DLL per ottenerli tutti.
    MARCO BREVEGLIERI
    Software and Web Developer, Teacher and Consultant

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

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.