Differenze tra le versioni di "Definizione ed uso dei Memory Stream"

Da Gambas-it.org - Wikipedia.
(13 versioni intermedie di uno stesso utente non sono mostrate)
Riga 1: Riga 1:
 
La classe '''Memory-Stream''' crea flussi di dati che utilizzano la RAM. Pertanto, i "''Memory-Stream''" sono dei ''flussi di dati in memoria''.
 
La classe '''Memory-Stream''' crea flussi di dati che utilizzano la RAM. Pertanto, i "''Memory-Stream''" sono dei ''flussi di dati in memoria''.
  
In sostanza la classe ''Memory-Stream'' serve per leggere e per scrivere in una variabile di tipo ''Puntatore'' che punta ad un'<I>area di memoria riservata</i>.
+
Con la versione 3 di Gambas non è possibile scrivere ''direttamente'' in un'area di memoria puntata da un ''Puntatore''. Per fare ciò è necessario utilizzare la risorsa "''Memory-Stream''", la quale da una variabile di tipo ''Puntatore'' crea una variabile di tipo ''Stream'' consentendo così di scrivervi (ma anche di leggervi).
 +
Dunque la risorsa ''Memory-Stream'' serve per leggere e in particolar modo per <SPAN Style="text-decoration:underline">scrivere</span> in una variabile di tipo ''Puntatore'' che punta ad un'<I>area di memoria riservata</i>.
 +
<BR>Dopo la <SPAN Style="text-decoration:underline">scrittura</span> bisognerà comunque utilizzare nel resto del codice la variabile ''Puntatore'': la variabile di tipo ''Stream'' in tal caso <SPAN Style="text-decoration:underline">serve soltanto per poter ''scrivere''</span> nell'area di memoria allocata e puntata dal "Puntatore".
  
 
Tale ''area di memoria'' può essere:
 
Tale ''area di memoria'' può essere:
Riga 7: Riga 9:
 
* un'area riservata avente una determinata dimensione allocata da noi mediante la funzione ''Alloc()'';
 
* un'area riservata avente una determinata dimensione allocata da noi mediante la funzione ''Alloc()'';
 
* quella di un ''Puntatore'' passato da una funzione esterna dichiarata con ''Extern''.
 
* quella di un ''Puntatore'' passato da una funzione esterna dichiarata con ''Extern''.
Una volta utilizzata
 
  
La scrittura e la lettura avviene utilizzando una variabile di tipo "''Stream''" generata dalla risorsa ''Memory-Stream'' partendo dalla variabile ''Puntatore''.
+
Come già detto, la scrittura e la lettura avviene utilizzando una variabile di tipo "''Stream''" generata dalla risorsa ''Memory-Stream'' partendo dalla variabile ''Puntatore''.
  
 
La sintassi dell'utilizzo dei ''Memory Stream'' è la seguente:
 
La sintassi dell'utilizzo dei ''Memory Stream'' è la seguente:
Riga 19: Riga 20:
 
Ovviamente, con riferimento al formato ''Big-Endian''/''Little-Endian'', la procedura di scrittura e di lettura dei dati nel flusso (''stream'') è identica alla procedura che avviene con i file.
 
Ovviamente, con riferimento al formato ''Big-Endian''/''Little-Endian'', la procedura di scrittura e di lettura dei dati nel flusso (''stream'') è identica alla procedura che avviene con i file.
  
Una volta utilizzata per leggere o per scrivere nel ''Puntatore'', la variabile di tipo ''Stream'' viene abbandonata chiudendo il flusso con il metodo ''variabile_Stream.Close'' .
+
Una volta utilizzata per leggere o per scrivere nel ''Puntatore'', la variabile di tipo ''Stream'' viene abbandonata chiudendo il flusso con il Metodo ''variabile_Stream.Close()'' .
  
  
Riga 28: Riga 29:
 
  '''Public''' Sub Main()
 
  '''Public''' Sub Main()
 
   
 
   
   Dim i As Integer               <Font Color=#B22222>' ''  int i;''</font>
+
   Dim i As Integer             <Font Color=#B22222>' ''  int i;''</font>
   Dim p As Pointer               <Font Color=#B22222>' ''  int * p;''</font>
+
   Dim p As Pointer             <Font Color=#B22222>' ''  int * p;''</font>
 
   Dim st As Stream
 
   Dim st As Stream
 
   
 
   
  <Font Color=gray>' ''Si dereferenzia il Puntatore, ossia si accede alla locazione di memoria puntata (quella della variabile "i"):''</font>
+
  <Font Color=gray>' ''Si assegna l'indirizzo di memoria della variabile "i" di tipo "Intero" alla variabile di tipo "Puntatore":''</font>
  p = VarPtr(i)                <Font Color=#B22222>' ''  p = &i;''</font>
+
  p = VarPtr(i)                <Font Color=#B22222>' ''  p = &i;''</font>
 
    
 
    
 
  <Font Color=gray>' ''Si scrive (in Gambas lo si fa usando una variabile di tipo "Stream") nella locazione di memoria puntata (quella della variabile "i"):''</font>
 
  <Font Color=gray>' ''Si scrive (in Gambas lo si fa usando una variabile di tipo "Stream") nella locazione di memoria puntata (quella della variabile "i"):''</font>
  st = Memory p For Write
+
  st = Memory p For Write
  Write #st, 99999 As Integer  <Font Color=#B22222>' ''  *p = 99999''</font>
+
  Write #st, 99999 As Integer  <Font Color=#B22222>' ''  *p = 99999''</font>
  st.Close
+
  st.Close
 
      
 
      
  Print "i =  "; i              <Font Color=#B22222>' ''  printf("i =  %d\n", i);''</font>
+
  Print "i =  "; i              <Font Color=#B22222>' ''  printf("i =  %d\n", i);''</font>
 
   
 
   
 
  '''End'''
 
  '''End'''
 +
La modalità in "Scrittura" (''For Write'' ) risulta ''particolarmente'' utile nel caso si debbano scrivere dei valori all'interno di un'area di memoria riservata, allocata con la funzione "Alloc()".
  
 
+
In questo esempio, si intende creare all'interno di un'area di memoria riservata con "Alloc()" una sequenza dei seguenti byte: &h80, &h81, &h82, &h83, lo si può fare scrivendo:
Ma la modalità in "Scrittura" (''For Write'') risulta ''particolarmente'' utile nel caso si debbano scrivere dei valori all'interno di un'area di memoria riservata, allocata con la funzione ''Alloc()'' .
+
  '''Public''' Sub Main()
 
 
In questo esempio, si intende creare all'interno di un'area di memoria riservata con ''Alloc()'' una sequenza dei seguenti byte: &h80, &h81, &h82, &h83, lo si può fare scrivendo:
 
'''Private''' st As Stream
 
 
 
  '''Public''' Sub Button1_Click()
 
 
   
 
   
 
   Dim p As Pointer
 
   Dim p As Pointer
 +
  Dim st As Stream
 
   Dim b As Byte
 
   Dim b As Byte
 
   
 
   
 
  <Font Color=gray>' ''Riserviamo 4 byte da qualche parte in memoria:''</font>
 
  <Font Color=gray>' ''Riserviamo 4 byte da qualche parte in memoria:''</font>
  p = Alloc(4)
+
  p = Alloc(SizeOf(gb.Byte), 4)
 
   
 
   
 
  <Font Color=gray>' ''Questa memoria sarà un flusso (stream) che creeremo appositamente, e...''</font>
 
  <Font Color=gray>' ''Questa memoria sarà un flusso (stream) che creeremo appositamente, e...''</font>
  st = Memory p For Write
+
  st = Memory p <Font Color=#B22222>For Write</font>
 
   
 
   
 
  <Font Color=gray>' ''...nel quale andiamo a scrivere i 4 valori byte.''
 
  <Font Color=gray>' ''...nel quale andiamo a scrivere i 4 valori byte.''
 
  ' ''Ogni valore byte occuperà la dimensione di 1 byte, quindi copriranno esattamente i 4 byte allocati:''</font>
 
  ' ''Ogni valore byte occuperà la dimensione di 1 byte, quindi copriranno esattamente i 4 byte allocati:''</font>
  For b = 80 to 83
+
  For b = 80 to 83
    Write #st, b As Byte
+
    Write #st, b As Byte
  Next
+
  Next
 
   
 
   
 
  <Font Color=gray>' ''Chiudiamo il flusso e liberiamo la parte di memoria precedentemente allocata:''</font>
 
  <Font Color=gray>' ''Chiudiamo il flusso e liberiamo la parte di memoria precedentemente allocata:''</font>
  st.Close
+
  st.Close
  Free(p)
+
  Free(p)
 
   
 
   
 
  '''End'''
 
  '''End'''
Riga 76: Riga 73:
  
 
==Memory Stream in modalità "For Read"==
 
==Memory Stream in modalità "For Read"==
In modalità "''For Read''" i Memory-Stream possono essere usati per [[Variabili_di_tipo_Puntatore_e_loro_dereferenziazione|dereferenziare i puntatori]].
+
In modalità "''For Read'' " i Memory-Stream possono essere usati per [[Variabili_di_tipo_Puntatore_e_loro_dereferenziazione|dereferenziare i puntatori]].
  
 
Per mostrare un esempio pratico, poniamo il caso che ad una sub-procedura venga passato un ''Puntatore'', che punta ad un'area riservata precedentemente allocata (come nell'esempio visto nel paragrafo di sopra) al fine di derefenziarlo con i ''Memory Stream''. Si procederà ad estrarre i valori contenuti in quest'aera riservata di memoria:
 
Per mostrare un esempio pratico, poniamo il caso che ad una sub-procedura venga passato un ''Puntatore'', che punta ad un'area riservata precedentemente allocata (come nell'esempio visto nel paragrafo di sopra) al fine di derefenziarlo con i ''Memory Stream''. Si procederà ad estrarre i valori contenuti in quest'aera riservata di memoria:
  '''Public''' Procedure Dereferenzia(p As Pointer)
+
  '''Public''' Sub Main()
 +
 +
  Dim p As Pointer
 +
  Dim st As Stream
 +
  Dim b As Byte
 +
 +
  p = Alloc(SizeOf(gb.Byte), 4)
 +
 +
  st = Memory p <Font Color=darkgreen>For Write</font>
 +
 +
  For b = 80 to 83
 +
    Write #st, b As Byte
 +
  Next
 +
<Font Color=gray>' ''Chiudiamo il flusso in "Scrittura":''</font>
 +
  st.Close
 +
 +
<Font Color=gray>' ''Invoca la funzione per dereferenziare il Puntatore:''</font>
 +
  Dereferenzia(p)
 +
 
 +
  Free(p)
 +
 +
'''End'''
 +
 +
'''Private''' Procedure Dereferenzia(p As Pointer)
 
   
 
   
 
   Dim j, b As Byte
 
   Dim j, b As Byte
 
   Dim st As Stream
 
   Dim st As Stream
 
 
   
 
   
 
  <Font Color=gray>' ''Generiamo la variabile di tipo "Stream" dal "Puntatore" che è stato passato con la chiamata della sub-procedura:''</font>
 
  <Font Color=gray>' ''Generiamo la variabile di tipo "Stream" dal "Puntatore" che è stato passato con la chiamata della sub-procedura:''</font>
  st As Stream
+
  st = Memory p <Font Color=#B22222>For Read</font>
 
   
 
   
 
  <Font Color=gray>' ''Riprendiamo l'esempio del paragrafo precedente, dove sono stati scritti 4 valori di tipo "byte"; e li andiamo ad "estrarre" leggendo dalla variabile di tipo "Stream":''</font>
 
  <Font Color=gray>' ''Riprendiamo l'esempio del paragrafo precedente, dove sono stati scritti 4 valori di tipo "byte"; e li andiamo ad "estrarre" leggendo dalla variabile di tipo "Stream":''</font>
  For j = 0 To 3
+
  For j = 0 To 3
    Read #st, b
+
    Read #st, b
    Print "---> ", b
+
    Print "---> ", b
  Next
+
  Next
 
   
 
   
  <Font Color=gray>' ''Chiudiamo il flusso:''</font>
+
  <Font Color=gray>' ''Chiudiamo il flusso in "Lettura":''</font>
  st.Close
+
  st.Close
 
   
 
   
 
  '''End'''
 
  '''End'''
Riga 102: Riga 121:
 
==Altri esempi sulla scrittura e lettura delle variabili di tipo "Stream"==
 
==Altri esempi sulla scrittura e lettura delle variabili di tipo "Stream"==
 
Scriviamo nello ''Stream'' un testo, poi lo recuperiamo leggendo lo ''Stream'':
 
Scriviamo nello ''Stream'' un testo, poi lo recuperiamo leggendo lo ''Stream'':
  '''Public''' Sub Button1_Click()
+
  '''Public''' Sub Main()
 
   
 
   
 
   Dim p As Pointer
 
   Dim p As Pointer
Riga 109: Riga 128:
 
   Dim j As Byte
 
   Dim j As Byte
 
    
 
    
    p = Alloc(4)
+
  p = Alloc(SizeOf(gb.Byte), 4)
 
      
 
      
    st = Memory p For Read Write
+
  st = Memory p For Read Write
 
      
 
      
    s = "testo qualsiasi"
+
  s = "testo qualsiasi"
 
      
 
      
 
  <Font Color= #006400>' ''Scriviamo la stringa nella variabile di tipo "Stream":''</font>
 
  <Font Color= #006400>' ''Scriviamo la stringa nella variabile di tipo "Stream":''</font>
    Print #st, s
+
  Print #st, s
 
   
 
   
  <Font Color= #006400>''''''''''''''''''''</font>
+
<Font Color= #006400>''''''''''''''''''''</font>
 
   
 
   
 
  <Font Color= #006400>' ''Leggiamo nella variabile di tipo "Stream"''</font>
 
  <Font Color= #006400>' ''Leggiamo nella variabile di tipo "Stream"''</font>
 
   
 
   
  <Font Color= #006400>' ''Poiché con la precedente scrittura l'indice dello "stream"''
+
  <Font Color= #006400>' ''Poiché con la precedente scrittura l'indice dello "stream" è incrementato di uno, si dovrà re-impostare la lettura all'indice zero:</font>
' ''è incrementato di uno, si dovrà re-impostare la lettura all'indice zero:</font>
+
  Seek #st, 0
      Seek #st, 0
+
  Line Input #st, ss
      Line Input #st, ss
 
 
   
 
   
      Print "Contenuto dello stream: "; ss
+
  Print "Contenuto dello stream: "; ss
 
   
 
   
 
  <Font Color= #006400>' ''Chiudiamo il flusso e liberiamo la parte di memoria precedentemente allocata:''</font>
 
  <Font Color= #006400>' ''Chiudiamo il flusso e liberiamo la parte di memoria precedentemente allocata:''</font>
    st.Close
+
  st.Close
    Free(p)
+
  Free(p)
 
   
 
   
 
  '''End'''
 
  '''End'''
 
  
 
Secondo esempio - leggiamo con l'istruzione ''Shell'' congiunta al comando bash "''ls''" nella cartella "''/proc''", e riportiamo in una ''TextArea'' il contenuto ivi letto distinguendo ciascuna sub-cartella o file mediante ''Input''. <BR>Nel codice scriveremo in un flusso per mezzo dei ''Memory Stream'' tutti i dati ricavati con ''ls''; e per verifica leggeremo dal flusso - sempre per mezzo dei ''Memory Stream'' - quei dati scritti poco prima:
 
Secondo esempio - leggiamo con l'istruzione ''Shell'' congiunta al comando bash "''ls''" nella cartella "''/proc''", e riportiamo in una ''TextArea'' il contenuto ivi letto distinguendo ciascuna sub-cartella o file mediante ''Input''. <BR>Nel codice scriveremo in un flusso per mezzo dei ''Memory Stream'' tutti i dati ricavati con ''ls''; e per verifica leggeremo dal flusso - sempre per mezzo dei ''Memory Stream'' - quei dati scritti poco prima:
Riga 143: Riga 160:
 
   Dim m As Stream
 
   Dim m As Stream
 
   Dim j As Integer
 
   Dim j As Integer
 
 
 
    
 
    
  Shell "ls /proc" To s
+
  Shell "ls /proc" To s
 
   
 
   
  <Font Color= #006400>' ''Allochiamo sufficiente memoria,''
+
  <Font Color= #006400>' ''Allochiamo sufficiente memoria, e vi puntiamo con una variabile di tipo "puntatore":''</font>
' ''e vi puntiamo con una variabile di tipo "puntatore":''</font>
+
  p = Alloc(SizeOf(gb.Byte), 2048)
  p = Alloc(2048)
 
 
    
 
    
 
  <Font Color= #006400>' ''Creiamo la variabile "m" di tipo "Stream":''</font>
 
  <Font Color= #006400>' ''Creiamo la variabile "m" di tipo "Stream":''</font>
  m = Memory p For Read Write
+
  m = Memory p For Read Write
 
    
 
    
 
  <Font Color= #006400>' ''Scriviamo nella variabile "m" il contenuto della variabile stringa "s":''</font>
 
  <Font Color= #006400>' ''Scriviamo nella variabile "m" il contenuto della variabile stringa "s":''</font>
 
   Print #m, s
 
   Print #m, s
 
   
 
   
+
  While Not Eof(m)
  While Not Eof(m)
 
 
  <Font Color= #006400>' ''Guidiamo la lettura nella variabile "m" mediante il comando "Seek":''</font>
 
  <Font Color= #006400>' ''Guidiamo la lettura nella variabile "m" mediante il comando "Seek":''</font>
    Seek #m, j
+
    Seek #m, j
    Input #m, ss
+
    Input #m, ss
 
 
  <Font Color= #006400>' ''Se non vi sono più dati relativi a caratteri alfanumerici, allora si esce dal ciclo:''</font>
 
  <Font Color= #006400>' ''Se non vi sono più dati relativi a caratteri alfanumerici, allora si esce dal ciclo:''</font>
      If ss = Null Then Exit
+
    If ss == Null Then Exit
+
    TextArea1.Text &= ss & Chr(10)
    TextArea1.Text &= ss & Chr(10)
+
  <Font Color= #006400>' ''Si dà il valore al comando "Seek per far cominciare" la lettura dal byte corrispondente nella variabile "s" ad ogni inizio riga:''</font>
+
    j = j + Len(ss) + 1
  <Font Color= #006400>' ''Si dà il valore al comando "Seek per far cominciare"''
+
  Wend
' ''la lettura dal byte corrispondente nella variabile "s" ad ogni inizio riga:''</font>
 
    j = j + Len(ss) + 1
 
 
  Wend
 
 
   
 
   
 
  <Font Color= #006400>' ''Liberiamo la parte di memoria precedentemente allocata:''</font>
 
  <Font Color= #006400>' ''Liberiamo la parte di memoria precedentemente allocata:''</font>
    m.Close
+
  m.Close
    Free(p)
+
  Free(p)
 
   
 
   
 
  '''End'''
 
  '''End'''
 
  
  
Riga 185: Riga 193:
 
Si procederà ugualmente per dereferenziare i puntatori <SPAN style="text-decoration:underline">passati da funzioni esterne</span>.
 
Si procederà ugualmente per dereferenziare i puntatori <SPAN style="text-decoration:underline">passati da funzioni esterne</span>.
  
  '''Public''' Sub Button1_Click()
+
  '''Public''' Sub Main()
 
   
 
   
   Dim pEst As Pointer
+
   Dim p As Pointer
   Dim pS As Stream
+
   Dim st As Stream
   Dim by As Byte
+
   Dim b As Byte
 
   
 
   
  <Font Color= #006400>' ''Prendiamo da una funzione esterna un valore di tipo puntatore:''</font>
+
  <Font Color=gray>' ''Prendiamo da una funzione esterna un valore di tipo puntatore:''</font>
  funzione_esterna_che_passa_un puntatore(pEst)
+
  p = funzione_esterna_che_passa_un_puntatore()
 +
<FONT Color=gray>' ''potrebbe anche essere così:'' '''funzione_esterna_che_passa_un_puntatore(VarPtr(p))'''</font>
 
   
 
   
  <Font Color= #006400>' ''Usiamo i Memory Stream in modalità di "lettura":''</font>
+
  <Font Color=gray>' ''Usiamo i Memory Stream in modalità di "lettura":''</font>
  pS = Memory pEst For Read
+
  st = Memory p For Read
 
   
 
   
  <Font Color= #006400>'Andiamo a dereferenziare e, quindi, a leggere il dato:''</font>
+
  <Font Color=gray>' ''Andiamo a dereferenziare e, quindi, a leggere il dato:''</font>
  Read #pS, by
+
  Read #st, b
 
   
 
   
  pS.Close
+
<Font Color=gray>' ''Chiudiamo il flusso di dati:''</font>
 +
  st.Close
 
    
 
    
  <Font Color= #006400>' ''Ora, a fini didattici, mostriamo il valore in console:''</font>
+
  <Font Color=gray>' ''Ora, ad esempio, mostriamo il valore in console:''</font>
  Print by
+
  Print b
 
   
 
   
 
  '''End'''
 
  '''End'''

Versione delle 17:35, 31 ott 2022

La classe Memory-Stream crea flussi di dati che utilizzano la RAM. Pertanto, i "Memory-Stream" sono dei flussi di dati in memoria.

Con la versione 3 di Gambas non è possibile scrivere direttamente in un'area di memoria puntata da un Puntatore. Per fare ciò è necessario utilizzare la risorsa "Memory-Stream", la quale da una variabile di tipo Puntatore crea una variabile di tipo Stream consentendo così di scrivervi (ma anche di leggervi). Dunque la risorsa Memory-Stream serve per leggere e in particolar modo per scrivere in una variabile di tipo Puntatore che punta ad un'area di memoria riservata.
Dopo la scrittura bisognerà comunque utilizzare nel resto del codice la variabile Puntatore: la variabile di tipo Stream in tal caso serve soltanto per poter scrivere nell'area di memoria allocata e puntata dal "Puntatore".

Tale area di memoria può essere:

  • quella di una variabile, dalla quale sarà stato creato un Puntatore (che punta all'indirizzo di detta variabile) con la funzione VarPtr();
  • un'area riservata avente una determinata dimensione allocata da noi mediante la funzione Alloc();
  • quella di un Puntatore passato da una funzione esterna dichiarata con Extern.

Come già detto, la scrittura e la lettura avviene utilizzando una variabile di tipo "Stream" generata dalla risorsa Memory-Stream partendo dalla variabile Puntatore.

La sintassi dell'utilizzo dei Memory Stream è la seguente:

variabile_Stream = MEMORY Puntatore FOR [ READ ] [ WRITE ]
  • Se la parola chiave READ viene specificata, allora è permessa la lettura.
  • Se la parola chiave WRITE viene specificata, allora è permessa la scrittura.

Ovviamente, con riferimento al formato Big-Endian/Little-Endian, la procedura di scrittura e di lettura dei dati nel flusso (stream) è identica alla procedura che avviene con i file.

Una volta utilizzata per leggere o per scrivere nel Puntatore, la variabile di tipo Stream viene abbandonata chiudendo il flusso con il Metodo variabile_Stream.Close() .


Memory Stream in modalità "For Write"

Si può quindi scrivere nella variabile Stream con l'istruzione "Write" o anche con l'istruzione "Print".

Riteniamo utile fare un semplice confronto con il codice C:

Public Sub Main()

 Dim i As Integer              '    int i;
 Dim p As Pointer              '    int * p;
 Dim st As Stream

' Si assegna l'indirizzo di memoria della variabile "i" di tipo "Intero" alla variabile di tipo "Puntatore":
 p = VarPtr(i)                 '    p = &i;
 
' Si scrive (in Gambas lo si fa usando una variabile di tipo "Stream") nella locazione di memoria puntata (quella della variabile "i"):
 st = Memory p For Write
 Write #st, 99999 As Integer   '    *p = 99999
 st.Close
   
 Print "i =  "; i              '    printf("i =  %d\n", i);

End

La modalità in "Scrittura" (For Write ) risulta particolarmente utile nel caso si debbano scrivere dei valori all'interno di un'area di memoria riservata, allocata con la funzione "Alloc()".

In questo esempio, si intende creare all'interno di un'area di memoria riservata con "Alloc()" una sequenza dei seguenti byte: &h80, &h81, &h82, &h83, lo si può fare scrivendo:

Public Sub Main()

 Dim p As Pointer
 Dim st As Stream
 Dim b As Byte

' Riserviamo 4 byte da qualche parte in memoria:
 p = Alloc(SizeOf(gb.Byte), 4)

' Questa memoria sarà un flusso (stream) che creeremo appositamente, e...
 st = Memory p For Write

' ...nel quale andiamo a scrivere i 4 valori byte.
' Ogni valore byte occuperà la dimensione di 1 byte, quindi copriranno esattamente i 4 byte allocati:
 For b = 80 to 83
   Write #st, b As Byte
 Next

' Chiudiamo il flusso e liberiamo la parte di memoria precedentemente allocata:
 st.Close
 Free(p)

End


Memory Stream in modalità "For Read"

In modalità "For Read " i Memory-Stream possono essere usati per dereferenziare i puntatori.

Per mostrare un esempio pratico, poniamo il caso che ad una sub-procedura venga passato un Puntatore, che punta ad un'area riservata precedentemente allocata (come nell'esempio visto nel paragrafo di sopra) al fine di derefenziarlo con i Memory Stream. Si procederà ad estrarre i valori contenuti in quest'aera riservata di memoria:

Public Sub Main()

 Dim p As Pointer
 Dim st As Stream
 Dim b As Byte

 p = Alloc(SizeOf(gb.Byte), 4)

 st = Memory p For Write

 For b = 80 to 83
   Write #st, b As Byte
 Next
' Chiudiamo il flusso in "Scrittura":
 st.Close

' Invoca la funzione per dereferenziare il Puntatore:
 Dereferenzia(p)
 
 Free(p)

End

Private Procedure Dereferenzia(p As Pointer)

 Dim j, b As Byte
 Dim st As Stream

' Generiamo la variabile di tipo "Stream" dal "Puntatore" che è stato passato con la chiamata della sub-procedura:
 st = Memory p For Read

' Riprendiamo l'esempio del paragrafo precedente, dove sono stati scritti 4 valori di tipo "byte"; e li andiamo ad "estrarre" leggendo dalla variabile di tipo "Stream":
 For j = 0 To 3
   Read #st, b
   Print "---> ", b
 Next

' Chiudiamo il flusso in "Lettura":
 st.Close

End


Altri esempi sulla scrittura e lettura delle variabili di tipo "Stream"

Scriviamo nello Stream un testo, poi lo recuperiamo leggendo lo Stream:

Public Sub Main()

 Dim p As Pointer
 Dim st As Stream
 Dim s, ss As String
 Dim j As Byte
 
 p = Alloc(SizeOf(gb.Byte), 4)
   
 st = Memory p For Read Write
   
 s = "testo qualsiasi"
   
' Scriviamo la stringa nella variabile di tipo "Stream":
 Print #st, s

'''''''''''''''

' Leggiamo nella variabile di tipo "Stream"

' Poiché con la precedente scrittura l'indice dello "stream" è incrementato di uno, si dovrà re-impostare la lettura all'indice zero:
 Seek #st, 0
 Line Input #st, ss

 Print "Contenuto dello stream: "; ss

' Chiudiamo il flusso e liberiamo la parte di memoria precedentemente allocata:
 st.Close
 Free(p)

End

Secondo esempio - leggiamo con l'istruzione Shell congiunta al comando bash "ls" nella cartella "/proc", e riportiamo in una TextArea il contenuto ivi letto distinguendo ciascuna sub-cartella o file mediante Input.
Nel codice scriveremo in un flusso per mezzo dei Memory Stream tutti i dati ricavati con ls; e per verifica leggeremo dal flusso - sempre per mezzo dei Memory Stream - quei dati scritti poco prima:

Public Sub Button1_Click()

 Dim s, ss As String
 Dim p As Pointer
 Dim m As Stream
 Dim j As Integer
 
 Shell "ls /proc" To s

' Allochiamo sufficiente memoria, e vi puntiamo con una variabile di tipo "puntatore":
 p = Alloc(SizeOf(gb.Byte), 2048)
 
' Creiamo la variabile "m" di tipo "Stream":
 m = Memory p For Read Write
 
' Scriviamo nella variabile "m" il contenuto della variabile stringa "s":
 Print #m, s

 While Not Eof(m)
' Guidiamo la lettura nella variabile "m" mediante il comando "Seek":
   Seek #m, j
   Input #m, ss
' Se non vi sono più dati relativi a caratteri alfanumerici, allora si esce dal ciclo:
   If ss == Null Then Exit
   TextArea1.Text &= ss & Chr(10)
' Si dà il valore al comando "Seek per far cominciare" la lettura dal byte corrispondente nella variabile "s" ad ogni inizio riga:
   j = j + Len(ss) + 1
 Wend

' Liberiamo la parte di memoria precedentemente allocata:
 m.Close
 Free(p)

End


In modalità "Lettura" per dereferenziare i puntatori passati da funzioni esterne

Si procederà ugualmente per dereferenziare i puntatori passati da funzioni esterne.

Public Sub Main()

 Dim p As Pointer
 Dim st As Stream
 Dim b As Byte

' Prendiamo da una funzione esterna un valore di tipo puntatore:
 p = funzione_esterna_che_passa_un_puntatore()
' potrebbe anche essere così: funzione_esterna_che_passa_un_puntatore(VarPtr(p))

' Usiamo i Memory Stream in modalità di "lettura":
 st = Memory p For Read

' Andiamo a dereferenziare e, quindi, a leggere il dato:
 Read #st, b

' Chiudiamo il flusso di dati:
 st.Close
 
' Ora, ad esempio, mostriamo il valore in console:
 Print b

End