Problema:
Ho riscontrato che, dopo aver aperto con OPEN "...." For Read Watch un file-device (in: /dev/...) per intercettarne il flusso dei dati che passano lì da un dispositivo esterno, se lo chiudo, e poi tento di riaprilo, non ci riesco: non si riapre più ! :hard:
Esempio:
Private fd As File
Public Sub ToggleButton1_Click()
If Last.value Then
' apro il file-device che mi interessa:
fd = Open "/dev/file-device_da_aprire" For Read Watch
Else
' chiudo il file-device:
Close #fd
Endif
End
Public Sub File_Read()
Dim b As Byte
Read #fd, b
' vedo in console i dati raccolti:
Print b
End
...ma perché ? ??? Non dovrebbe comportarsi come un "file" qualsiasi ?
(Aprendolo come processo con Process, riesco, se lo chiudo, a riaprirlo, ma... questa è un'altra storia...)
mi sembra che non sia una bella cosa aprire un device in quel modo, dovresti creare una pipe (non chiedermi come :) )
altrimenti prova a leggere i dati con cat /dev/ecc,
Perché ritieni che non sia proprio ortodosso aprire un file-device con OPEN ?
Relativamente alla possibilità di creare una "pipe", neppure io ad oggi so ! Qualche altro "mostro sacro"⚛ di questo forum può dire/suggerire qualcosa al riguardo ?
Invece, per quanto riguarda il tentativo con cat /dev/ecc, questo l'ho già fatto. E' appunto il riferimento che facevo a Process. Confesso che non ci avevo pensato, prima; poi ho fatto il tentativo, e la ricezione dei dati funziona. Come ho già scritto, gestendo con Process funziona anche l'interruzione e la riapertura del flusso di dati dal file-device.
Ho fatto sostanzialmente così:
Private flDev As Process
Public Sub ToggleButton1_Click()
If Last.value Then
' apro il file-device:
flDev = Exec ["cat", "/dev/file_device_da_gestire"] For Read As "flDev"
Else
' lo chiudo; ma se ri-clicco sul ToggleButton riesco a riaprire il File-Device:
fdDev.Kill
Endif
End
Public Sub flDev_Read()
Dim b As Byte
Read #flDev, b
Print b
End
dovresti creare una pipe (non chiedermi come :) )
Forse qua ? :-\
http://gambasdoc.org/help/lang/pipe
Per cominciare a vedere se leggo i dati, avrei scritto una cosa di questo genere: :-X
flSt As File
Public Sub Form_Open()
flSt = Pipe "/dev/file_device_da_gestire" For Read Watch
End
Public Sub Pipe_Read()
Dim b As Byte
Read #flSt, b
Print b
End
...ma non vedo dati comparire in console ! :skull:
:-\
Quindi, prima di parlare di perchè "non funziona", sarebbe il caso che ci spiegassi cosa stai cercando di fare, e non in modo così generico... :-\
Sì, hai ragione: ci vuole "precisione".
Dunque... l'argomento da me posto è relativo all'intercettazione di dati grezzi provenienti da un dispositivo Midi (...tanto per cambiare ;D ) esterno (per esempio una tastiera). In vero, non ho problemi nell'intercettare tali dati, poiché i modi possono essere diversi (Vedi in basso nota 1).
Quasi tutti (tranne uno) i programmini da me realizzati, che intercettano dati Midi dall'esterno, adoperano questa riga di comando:
flusso = OPEN "/dev/snd/midiC2D0" For Read Watch
laddove "/dev/snd/midiC2D0" è il file-device che viene creato nel momento in cui viene connessa una tastiera Midi al PC.
Ad un certo punto... mi è venuto in mente di offrire all'utente la possibilità, dopo aver aperto il file-device per ricevere i dati, di richiuderlo mediante:
per bloccare l'intercettazione dei dati (cosa che avviene); nonché di consentirgli poi di ri-aprirlo, qualora voglia ricominciare a ricevere dati dal dispositivo Midi esterno, passando nuovamente per la riga di apertura con OPEN.
Ebbene, la riapertura non avviene.
Se, invece, questo procedimento lo effettuo gestendo il file-device con Process, posso chiuderlo e riaprirlo tutte le volte che voglio.
Lo so... qualcuno potrebbe dire:« Allora opera con "Process" ! ». Ma non vorrei usare Exec o Shell. Inoltre a questo punto vorrei comprendere la questione.
Vorrei fare un aggiornamento sulla questione di Pipe, poco sopra esposta.
Ho provato a fare una modifica alla riga: Public Sub Pipe_Read(). Avevo scritto Pipe_Read(), come avevo letto nella guida:
« Se la parola chiave WATCH viene specificata, la pipe viene vista dall'interprete come:
* Se alla fine della pipe può essere letto un byte, allora viene chiamato l'evento Pipe_Read(). ».
Ma come ho già detto, non leggo dati. Ed allora ho modificato quella riga così:
...e così funziona, nel senso che l'evento è sollevato, ed io sono in grado di leggere i dati.
Però, anche con Pipe se chiudo, e poi voglio ri-aprire il flusso, non si ri-apre (così come succedeva con Open), e non posso dunque tornare a leggere dati.
Un paio di domande:
* come mai con Pipe_Read() non viene sollevato l'evento ?
* ma soprattutto... in questo caso è meglio usare "Pipe" al posto di "Open" ? ???
Note:
[1] Al riguardo vedi: http://www.gambas-it.org/wiki/index.php/Gestione_del_MIDI_con_ALSA#Alsa_e_Gambas:_Gestione_dei_dati_Midi_in_.22Ricezione_dati.22 (http://www.gambas-it.org/wiki/index.php/Gestione_del_MIDI_con_ALSA#Alsa_e_Gambas:_Gestione_dei_dati_Midi_in_.22Ricezione_dati.22)
P.S.: A proposito, ma "cesko" l'hanno preso le guardie?!?
...effettivamente...... è sparito ! ???
Aggiungo che la storia non è proprio del tutto finita: sto facendo alcune prove e riscontri. :coder: Vi farò sapere.
Qualcuno :angel: mi ha suggerito di fare un test con il Timer, estromettendo quindi la parola "Watch":
fdMid As File
Public Sub Form_Open()
fdMid = Open "/dev/snd/midiC2D0"
End
Public Sub Timer1_Timer()
Dim b As Byte
While Not Lof(fdMid)
Read #fdMid, b
Print b
Wend
End
Public Sub Button1_MouseDown() ' chiude il file-device
Timer1.Stop
Close #fdMid
End
Public Sub Button2_MouseDown() ' Ri-apre il file-device
Timer1.start
Form_Open()
End
Dunque, effettuato il test con Timer senza Watch, riesco a chiudere e poi a ri-aprire il file-device. Ciò farebbe pensare che ci sia quindi un problema con la sollevazione dell'evento, con Watch (....un baco di Gambas ? :hatecomputer: ).
C'è una curiosità con l'uso di Timer: come avrete notato, ho scritto la riga di apertura del file-device senza neppure "For Read". Infatti se faccio la prova con la riga:
fdMid = Open "/dev/snd/midiC2D0" For Read
non ricevo dati ! ???
Li ricevo, solo se scrivo così:
fdMid = Open "/dev/snd/midiC2D0"
:rolleyes:
Mi sembra davvero incomprensibile questo fatto ! Perché con quella soluzione con Timer non posso usare la parola "For Read" ? ??? Che problemi ed implicazioni porterebbe all'apertura o alla lettura del file-device ? "For Read" non significa semplicemente che il file è aperto al fine di essere letto ? ...un altro baco-Gambas ? O[[[[[[[[[[[[
Potresti allegare la porzione di codice che ti da il problema così che possa provarla e vedere di trovare una soluzione?
Ti ringrazio per il tuo intervento.
Per quanto riguarda il codice, puoi facilmente copiare quello che ho scritto nel primo messaggio sopra, all'inizio.
Poi devi solo fare due cose:
1) Inserire un ToggleButton sul form;
2) cambiare la riga: fd = Open "/dev/file-device_da_aprire" For Read Watch con quest'altra:
fd = OPEN "/dev/snd/midiC2D0" For Read Watch
Per testare il codice, però, ovviamente dovrai avere a disposizione un dispositivo Midi esterno (ad esempio una tastiera con uscita Midi). Ricorda di collegare la tastiera Midi dopo aver avviato il sistema operativo, e prima di lanciare il codice.