Differenze tra le versioni di "Leggere e scrivere direttamente nell'area di memoria di una Struttura accedendovi con la classe Object"

Da Gambas-it.org - Wikipedia.
(Leggere e scrivere con i Memory Stream)
 
(20 versioni intermedie di uno stesso utente non sono mostrate)
Riga 28: Riga 28:
 
    
 
    
 
  <FONT Color=gray>' ''Dereferenzia il "Puntatore" mediante le funzioni native di Gambas di dereferenziazione, rispettando, laddove necessario, la regola dell'Allineamento dei dati all'interno della "Struttura":''</font>
 
  <FONT Color=gray>' ''Dereferenzia il "Puntatore" mediante le funzioni native di Gambas di dereferenziazione, rispettando, laddove necessario, la regola dell'Allineamento dei dati all'interno della "Struttura":''</font>
   Print Byte@(Object.Data(st))
+
   Print Byte@(<FONT Color=#B22222><B>Object.Data</b></font>(st))
   Print Short@(Object.Data(st) + 2)
+
   Print Short@(<FONT Color=#B22222><B>Object.Data</b></font>(st) + SizeOf(gb.Short))
   Print Integer@(Object.Data(st) + 4)
+
   Print Integer@(<FONT Color=#B22222><B>Object.Data</b></font>(st) + SizeOf(gb.Integer))
 +
 +
End
 +
 
 +
===Leggere i dati presenti nell'area di memoria di una ''Struttura'' mediante i Memory Stream===
 +
Mostriamo un esempio pratico:
 +
Public Struct STRUTTURA
 +
  b As Byte
 +
  c As Short
 +
  i As Integer
 +
End Struct
 +
 +
 +
Public Sub Main()
 +
 +
  Dim st As New STRUTTURA
 +
  Dim sm As Stream
 +
  Dim b As Byte
 +
  Dim c As Short
 +
  Dim i As Integer
 +
 
 +
  With st
 +
    .b = 111
 +
    .c = 2222
 +
    .i = 333333
 +
  End With
 +
   
 +
<FONT Color=gray>' ''Legge i dati presenti nell'area di memoria dell'Oggetto "Struttura", destinata al salvataggio dei dati, dereferenziando il "Puntatore" mediante la risorsa "Memory Stream", anche in questo caso rispettando, laddove necessario, la regola dell'Allineamento dei dati all'interno della "Struttura":''</font>
 +
  sm = Memory <FONT Color=#B22222>'''Object.Data'''</font>(st) For Read
 +
  <FONT Color=darkorange>Read</font> #sm, b
 +
<FONT Color=gray>' ''In questo caso rispetta la regola dell'Allineamento dei dati, avanzando di un byte:''</font>
 +
  Seek #sm, 2
 +
  <FONT Color=darkorange>Read</font> #sm, c
 +
  <FONT Color=darkorange>Read</font> #sm, i
 +
  sm.Close
 +
 +
<FONT Color=gray>' ''Effettua la verifica:''</font>
 +
  Print b
 +
  Print c
 +
  Print i
 +
 +
End
 +
 
 +
===Scrivere dati nell'area di memoria di una ''Struttura'' mediante i Memory Stream===
 +
Mostriamo un esempio pratico:
 +
Public Struct STRUTTURA
 +
  b As Byte
 +
  c As Short
 +
  i As Integer
 +
End Struct
 +
 +
 +
Public Sub Main()
 +
 +
  Dim st As New STRUTTURA
 +
  Dim sm As Stream
 +
   
 +
<FONT Color=gray>' ''Scrive dei dati all'interno dell'area di memoria dell'Oggetto "Struttura", destinata al salvataggio dei dati, usando la risorsa "Memory Stream", anche in questo caso rispettando, laddove necessario, la regola dell'Allineamento dei dati all'interno della "Struttura":''</font>
 +
  sm = Memory <FONT Color=#B22222>'''Object.Data'''</font>(st) For Write
 +
  <FONT Color=darkgreen>Write</font> #sm, 111 As byte
 +
<FONT Color=gray>' ''In questo caso rispetta la regola dell'Allineamento dei dati, avanzando di un byte:''</font>
 +
  <FONT Color=darkgreen>Write</font> #sm, 0 As Byte
 +
  <FONT Color=darkgreen>Write</font> #sm, 2222 As Short
 +
  <FONT Color=darkgreen>Write</font> #sm, 333333 As Integer
 +
  sm.Close
 +
 +
 +
<FONT Color=gray>' ''Effettua la verifica:''</font>
 +
  With st
 +
    Print .b
 +
    Print .c
 +
    Print .i
 +
  End With
 
   
 
   
 
  End
 
  End
Riga 37: Riga 109:
 
=Leggere e scrivere direttamente nell'area di memoria di una ''Struttura'' usando il Metodo "Object.Address()"=
 
=Leggere e scrivere direttamente nell'area di memoria di una ''Struttura'' usando il Metodo "Object.Address()"=
 
Anche nel caso di uso del Metodo "Object.Address()" è possibile leggere e scrivere direttamente all'interno dell'area di memoria di una ''Struttura'' attraverso le funzioni naive di Gambas di dereferenziazione dei ''Puntatori'' oppure tramite la risorsa ''Memory Stream''.
 
Anche nel caso di uso del Metodo "Object.Address()" è possibile leggere e scrivere direttamente all'interno dell'area di memoria di una ''Struttura'' attraverso le funzioni naive di Gambas di dereferenziazione dei ''Puntatori'' oppure tramite la risorsa ''Memory Stream''.
 +
 +
Va ricordato che la lettura e la scrittura avverranno, prendendo come punto di riferimento iniziale, il 25° (indice 24) byte di quell'area di memoria <SUP>&#091;[[#Note|nota 1]]&#093;</sup>. Ciò si spiega con il fatto che il Metodo "Object.Address()" restituisce l'indirizzo di un Oggetto Gambas (in tal caso una Struttura) in memoria, non l'indirizzo dei dati associati alla ''Struttura''.
  
 
===Leggere una Struttura mediante le funzioni specifiche di dereferenziazione dei Puntatori===
 
===Leggere una Struttura mediante le funzioni specifiche di dereferenziazione dei Puntatori===
Riga 51: Riga 125:
 
   
 
   
 
   
 
   
  '''Public''' Sub Main()
+
  Public Sub Main()
 
   
 
   
 
   Dim st As New STRUTTURA
 
   Dim st As New STRUTTURA
Riga 63: Riga 137:
 
   
 
   
 
  <FONT Color=gray>' ''Assegnamo al "Puntatore" l'indirizzo di memoria della variabile della "Struttura":''</font>
 
  <FONT Color=gray>' ''Assegnamo al "Puntatore" l'indirizzo di memoria della variabile della "Struttura":''</font>
   p = Object.Address(st)
+
   p = <FONT Color=#B22222>'''Object.Address'''</font>(st)
 
      
 
      
 
  <FONT Color=gray>' ''Per scorrere all'interno del "Puntatore" lo sommiamo di volta in volta con un valore adeguato ad individuare il tipo di membro della "Struttura".''
 
  <FONT Color=gray>' ''Per scorrere all'interno del "Puntatore" lo sommiamo di volta in volta con un valore adeguato ad individuare il tipo di membro della "Struttura".''
Riga 69: Riga 143:
 
  ' ''Procede in questo caso come segue:''</font>
 
  ' ''Procede in questo caso come segue:''</font>
 
   
 
   
  <FONT Color=gray>' ''Avanza al byte dell'area di memoria della Struttura occupato dal membro di tipo "Byte"''</font>
+
  <FONT Color=gray>' ''Avanza al byte dell'area di memoria della Struttura'' <SUP>&#091;[[#Note|nota 1]]&#093;</sup>'', occupato dal membro di tipo "Byte"''</font>
 
   Print Byte@(p + '''24''')
 
   Print Byte@(p + '''24''')
 
   
 
   
  <FONT Color=gray>' ''Rispetto al byte d'indice 24 si deve avanzare di un byte per il necessario "allineamento" del primo e del secondo membro della Struttura; altresì si deve avanzare di un altro byte per giungere al dato-byte iniziale dei 2 byte dell'area di memoria della Struttura occupati dal membro di tipo "Short"''</font>
+
  <FONT Color=gray>' ''Rispetto al byte d'indice 24 si deve avanzare di un byte per il necessario "allineamento" del primo e del secondo membro della Struttura; altresì si deve avanzare di un altro byte per giungere al dato-byte iniziale dei 2 byte occupati dal membro di tipo "Short"''</font>
   Print Short@(p + (24 + '''1''' + '''1''')
+
   Print Short@(p + (24 + '''1''' + '''1'''))
 +
<FONT Color=gray>' ''o anche:'' '''Print Short@(p + (24 + SizeOf(gb.Short)))'''</font>
 
   
 
   
  <FONT Color=gray>' ''Rispetto al byte d'indice 24 si deve avanzare di altri due byte per raggiungere il dato-byte iniziale dei 4 byte dell'area di memoria della Struttura occupati dal membro di tipo "Integer"''</font>
+
  <FONT Color=gray>' ''Rispetto al byte d'indice 24 si deve avanzare di altri due byte per raggiungere il dato-byte iniziale dei 4 byte occupati dal membro di tipo "Integer"''</font>
 
   Print Int@(p + (24 + 1 + 1 + '''2'''))
 
   Print Int@(p + (24 + 1 + 1 + '''2'''))
 +
<FONT Color=gray>' ''o anche:'' '''Print Int@(p + (24 + SizeOf(gb.Integer)))'''</font>
 
   
 
   
  '''End'''
+
  End
  
===Leggere e scrivere con i Memory Stream===
+
===Leggere e scrivere nell'area di memoria di una ''Struttura'' mediante i Memory Stream===
 
Come sappiamo, una ''Struttura'' in sostanza non è altro che un'area riservata di memoria suddivisa al suo interno per settori (''membri'') di dimensione fra loro non (necessariamente) omogenea.
 
Come sappiamo, una ''Struttura'' in sostanza non è altro che un'area riservata di memoria suddivisa al suo interno per settori (''membri'') di dimensione fra loro non (necessariamente) omogenea.
  
Lo scopo, quindi, è assegnare tale area di memoria ad un ''Puntatore'', e successivamente attraverso i ''[[Definizione_ed_uso_dei_Memory_Stream|Memory Stream]]'' <SUP>&#091;[[#Note|nota 1]]&#093;</sup> andare a leggere e/o scrivere in tale area, ossia nella ''Struttura''. Come è evidente, dunque, il processo di lettura e di scrittura all'interno dei membri della ''Struttura'' avverrà in modo diverso, atipico rispetto alla normale modalità di lettura/assegnazione di valori che avviene richiamando direttamente i membri della ''Struttura'' medesima.
+
Lo scopo, quindi, è assegnare tale area di memoria ad un ''Puntatore'', e successivamente attraverso i ''[[Definizione_ed_uso_dei_Memory_Stream|Memory Stream]]'' andare a leggere e/o scrivere in tale area, ossia nella ''Struttura''. Come è evidente, dunque, il processo di lettura e di scrittura all'interno dei membri della ''Struttura'' avverrà in modo diverso, atipico rispetto alla normale modalità di lettura/assegnazione di valori che avviene richiamando direttamente i membri della ''Struttura'' medesima.
 
 
Va ricordato che la lettura e la scrittura avveraanno prendendo come punto di riferimento iniziale il 25° (indice 24) byte di quell'area di memoria - i dati prescelti. Ciò si spiega con il fatto che il Metodo "Object.Address()" restituisce l'indirizzo di un Oggetto Gambas (in tal caso una Struttura) in memoria, non l'indirizzo dei dati a cui fa riferimento.  
 
  
Mostriamo dunque un esempio,pratico: <SUP>&#091;[[#Note|nota 2]]&#093;</sup>
+
Mostriamo dunque un esempio,pratico:
 
  Public Struct STRUTTURA
 
  Public Struct STRUTTURA
 
   b As Byte
 
   b As Byte
Riga 95: Riga 169:
 
   
 
   
 
   
 
   
  '''Public''' Sub Main()
+
  Public Sub Main()
 
   
 
   
 
   Dim stru As New STRUTTURA
 
   Dim stru As New STRUTTURA
  Dim p As Pointer
 
 
   Dim st As Stream
 
   Dim st As Stream
 
   Dim b, j As Byte
 
   Dim b, j As Byte
Riga 109: Riga 182:
 
   End With
 
   End With
 
   
 
   
  <FONT Color=gray>' ''Otteniamo l'indirizzo di memoria della Struttura:''</font>
+
  <FONT Color=gray>' ''Ottiene dal Puntatore, ritornato dal Metodo "Object.Address()", uno "Stream" in lettura e scrittura:''</font>
   p = <FONT Color=#B22222><B>Object.Address</b></font>(stru)
+
   st = Memory <FONT Color=#B22222><B>Object.Address</b></font>(stru) For Read Write
 
   
 
   
  <FONT Color=gray>' ''Otteniamo dal Puntatore uno "Stream" in lettura e scrittura:''</font>
+
  <FONT Color=gray>' ''Legge i valori contenuti nell'area di memoria della Struttura, per la sua intera dimensione, alla quale aggiungiamo 24 byte'' <SUP>&#091;[[#Note|nota 1]]&#093;</sup>'', dato che - utilizzando la parola "New" nella dichiarazione dela variabile di tipo "Struttura" ed il Metodo "Object.Address()" - il valore del primo membro è posizionato al 25° byte (indice 24) dello "stream".''
  st = Memory p For Read Write
+
' ''I valori saranno mostrati in rappresentazione esadecimale.''</font>
 
<FONT Color=gray>' ''Leggiamo i valori contenuti nell'area di memoria della Struttura, per la sua intera dimensione, alla quale aggiungiamo 24 byte, dato che - utilizzando la parola "New" nella dichiarazione dela variabile di tipo "Struttura" ed il Metodo "Object.Address()" per ottenerne l'indirizzo di memoria - il valore del primo membro è posizionato al 25° byte (indice 24) dello "stream":</font>
 
 
   For j = 0 To 24 + Object.SizeOf(stru) - 1
 
   For j = 0 To 24 + Object.SizeOf(stru) - 1
     Read #st, b
+
     <FONT Color=darkorange>Read</font> #st, b
 
     If j == 24 Then  
 
     If j == 24 Then  
       Print "\e[31m"; j, Hex(b, 2)
+
       Print "\e[31m\e[1m"; j, Hex(b, 2)
 
     Else
 
     Else
 
       Print j, Hex(b, 2)
 
       Print j, Hex(b, 2)
Riga 125: Riga 196:
 
   Next
 
   Next
 
   
 
   
  <FONT Color=gray>' ''Modifichiamo un valore (in questo caso quello del secondo membro, quello di tipo "Short") all'interno della Struttura usando lo "stream" precedentemente creato:''</font>
+
  <FONT Color=gray>' ''Modifica un valore (in questo caso quello del secondo membro, quello di tipo "Short") all'interno della Struttura usando lo "stream" precedentemente creato:''</font>
   Seek #st, 26
+
   Seek #st, 24 + SizeOf(gb.Short)
   Write #st, &0987 As Short
+
   <FONT Color=darkgreen>Write</font> #st, &0987 As Short
 
   
 
   
 
   st.Close
 
   st.Close
 
   
 
   
  <FONT Color=gray>' ''Verifichiamo la scrittura del dato, leggendo ora direttamente il membro di tipo "Short" della Struttura:''</font>
+
  <FONT Color=gray>' ''Verifica la scrittura del dato, leggendo ora direttamente il membro di tipo "Short" della Struttura:''</font>
 
     Print "\n\e[0m"; Hex(stru.s, 4)
 
     Print "\n\e[0m"; Hex(stru.s, 4)
 
   
 
   
  '''End'''
+
  End
 +
Altro esempio analogo al precedente, ma in sola "Lettura" con i ''Memory Stream'':
 +
Public Struct STRUTTURA
 +
  b As Byte
 +
  c As Short
 +
  i As Integer
 +
End Struct
 +
 +
 +
Public Sub Main()
 +
 +
  Dim st As New STRUTTURA
 +
  Dim sm As Stream
 +
  Dim b As Byte
 +
  Dim c As Short
 +
  Dim i As Integer
 +
 
 +
  With st
 +
    .b = 111
 +
    .c = 2222
 +
    .i = 333333
 +
  End With
 +
   
 +
<FONT Color=gray>' ''Legge i dati presenti nell'area di memoria dell'Oggetto "Struttura" dereferenziando il "Puntatore" mediante la risorsa "Memory Stream", anche in questo caso rispettando, laddove necessario, la regola dell'Allineamento dei dati all'interno della "Struttura":''</font>
 +
  sm = Memory <FONT Color=#B22222>'''Object.Address'''</font>(st) For Read
 +
<FONT Color=gray>' ''Pone il "Puntatore della risorsa "Stream" al byte di indice 24, ove sono immagazzinati i dati nella "Struttura":''</font>
 +
  Seek #sm, 24
 +
  <FONT Color=darkorange>Read</font> #sm, b
 +
<FONT Color=gray>' ''In questo caso rispetta la regola dell'Allineamento dei dati, avanzando di un byte:''</font>
 +
  Seek #sm, 26
 +
  <FONT Color=darkorange>Read</font> #sm, c
 +
  <FONT Color=darkorange>Read</font> #sm, i
 +
  sm.Close
 +
 +
 +
<FONT Color=gray>' ''Effettua la verifica:''</font>
 +
  Print b
 +
  Print c
 +
  Print i
 +
 +
End
 +
Altro esempio, ma in sola "Scrittura" con i ''Memory Stream'':
 +
Public Struct STRUTTURA
 +
  b As Byte
 +
  s As Short
 +
  i As Integer
 +
End Struct
 +
 +
 +
Public Sub Main()
 +
 +
  Dim stru As New STRUTTURA
 +
  Dim st As Stream
 +
  Dim b As Byte
 +
   
 +
<FONT Color=gray>' ''Ottiene dal Puntatore, ritornato dal Metodo "Object.Address()", uno "Stream" in Scrittura:''</font>
 +
  st = Memory <FONT Color=#B22222>'''Object.Address'''</font>(stru) For Write
 +
 
 +
<FONT Color=gray>' ''Scrive dei valori nell'area riservata di memoria a cominciare dal byte d'indice offset n. 24 nel rispetto della disposizione dei byte all'interno dell'analoga area di memoria della "Struttura" secondo la regola dell'Allineamento dei dati:''</font>
 +
  Seek #st, 24
 +
  <FONT Color=darkgreen>Write</font> #st, 111 As Byte
 +
  <FONT Color=darkgreen>Write</font> #st, 0 As Byte    <FONT Color=gray>' ''Avanza di un byte per rispettare la regola dell'Allineamento dei dati''</font>
 +
  <FONT Color=darkgreen>Write</font> #st, 2222 As Short
 +
  <FONT Color=darkgreen>Write</font> #st, 333333 As Integer
 +
 +
  st.Close
 +
 +
 +
<FONT Color=gray>' ''Verifica i valori ora presenti nei tre membri della "Struttura":''</font>
 +
  With stru
 +
    Print .b
 +
    Print .s
 +
    Print .i
 +
  End With
 +
 
 +
End
  
=Note=
 
[1] Vedere anche: [[Assegnare valori ad una Struttura mediante i Memory Stream]]
 
  
[2] Vedere anche: [[Ottenere il puntatore di una variabile di tipo Struttura]]
 
  
 
+
=Note=
 
+
[1] Vedere anche: [[Ottenere il puntatore di una variabile di tipo Struttura]]
<FONT Color=red size=5>'''Pagina in costruzione !'''</font>
 

Versione attuale delle 12:41, 1 nov 2024

Per poter leggere e scrivere dati in una Struttura, oltre all'uso più semplice dei suoi membri, è possibile accedere direttamente all'area di memoria della Struttura mediante i seguenti Metodi della Classe Object:

  • "Object.Data()", il quale ritorna un Puntatore all'indirizzo di memoria ove sono referenziati i dati contenuti dai membri della Struttura;
  • "Object.Address()", che ritorna l'indirizzo di memoria dell'Oggetto Struttura.

Leggere e scrivere direttamente nell'area di memoria di una Struttura usando il Metodo "Object.Data()"

La lettura nell'area di memoria di una Struttura potrà avvenire attraverso le funzioni native di Gambas di dereferenziazione dei Puntatori oppure tramite la risorsa Memory Stream.

Leggere una Struttura mediante le funzioni specifiche di dereferenziazione dei Puntatori

E' possibile leggere i valori dei membri di una Struttura facendo riferimento alla relativa variabile di tipo Struttura mediante un Puntatore e derefenziandolo con le funzioni native specifiche di dereferenziazione.

Mostriamo un esempio pratico:

Public Struct STRUTTURA
  b As Byte
  c As Short
  i As Integer
End Struct


Public Sub Main()

 Dim st As New STRUTTURA
 
 With st
   .b = 111
   .c = 2222
   .i = 333333
 End With
 
' Dereferenzia il "Puntatore" mediante le funzioni native di Gambas di dereferenziazione, rispettando, laddove necessario, la regola dell'Allineamento dei dati all'interno della "Struttura":
 Print Byte@(Object.Data(st))
 Print Short@(Object.Data(st) + SizeOf(gb.Short))
 Print Integer@(Object.Data(st) + SizeOf(gb.Integer))

End

Leggere i dati presenti nell'area di memoria di una Struttura mediante i Memory Stream

Mostriamo un esempio pratico:

Public Struct STRUTTURA
  b As Byte
  c As Short
  i As Integer
End Struct


Public Sub Main()

 Dim st As New STRUTTURA
 Dim sm As Stream
 Dim b As Byte
 Dim c As Short
 Dim i As Integer
 
 With st
   .b = 111
   .c = 2222
   .i = 333333
 End With
   
' Legge i dati presenti nell'area di memoria dell'Oggetto "Struttura", destinata al salvataggio dei dati, dereferenziando il "Puntatore" mediante la risorsa "Memory Stream", anche in questo caso rispettando, laddove necessario, la regola dell'Allineamento dei dati all'interno della "Struttura":
 sm = Memory Object.Data(st) For Read
 Read #sm, b
' In questo caso rispetta la regola dell'Allineamento dei dati, avanzando di un byte:
 Seek #sm, 2
 Read #sm, c
 Read #sm, i
 sm.Close

' Effettua la verifica:
 Print b
 Print c
 Print i

End

Scrivere dati nell'area di memoria di una Struttura mediante i Memory Stream

Mostriamo un esempio pratico:

Public Struct STRUTTURA
  b As Byte
  c As Short
  i As Integer
End Struct


Public Sub Main()

 Dim st As New STRUTTURA
 Dim sm As Stream
   
' Scrive dei dati all'interno dell'area di memoria dell'Oggetto "Struttura", destinata al salvataggio dei dati, usando la risorsa "Memory Stream", anche in questo caso rispettando, laddove necessario, la regola dell'Allineamento dei dati all'interno della "Struttura":
 sm = Memory Object.Data(st) For Write
 Write #sm, 111 As byte
' In questo caso rispetta la regola dell'Allineamento dei dati, avanzando di un byte:
 Write #sm, 0 As Byte
 Write #sm, 2222 As Short
 Write #sm, 333333 As Integer
 sm.Close


' Effettua la verifica:
 With st
   Print .b
   Print .c
   Print .i
 End With

End


Leggere e scrivere direttamente nell'area di memoria di una Struttura usando il Metodo "Object.Address()"

Anche nel caso di uso del Metodo "Object.Address()" è possibile leggere e scrivere direttamente all'interno dell'area di memoria di una Struttura attraverso le funzioni naive di Gambas di dereferenziazione dei Puntatori oppure tramite la risorsa Memory Stream.

Va ricordato che la lettura e la scrittura avverranno, prendendo come punto di riferimento iniziale, il 25° (indice 24) byte di quell'area di memoria [nota 1]. Ciò si spiega con il fatto che il Metodo "Object.Address()" restituisce l'indirizzo di un Oggetto Gambas (in tal caso una Struttura) in memoria, non l'indirizzo dei dati associati alla Struttura.

Leggere una Struttura mediante le funzioni specifiche di dereferenziazione dei Puntatori

E' possibile leggere i valori dei membri di una Struttura facendo riferimento alla relativa variabile di tipo Struttura mediante un Puntatore e derefenziandolo con le funzioni specifiche di dereferenziazione.

In particolare, la procedura prevede dapprima l'assegnazione dell'indirizzo di memoria della variabile della Struttura ad una variabile di tipo Puntatore, e successivamente la dereferenziazione graduale di tale Puntatore, leggendo al suo interno rispettando i byte di memoria occupati da ciascun membro della Struttura ed eventualmente effettuando i necessari allineamenti dei membri.

Mostriamo un semplice esempio:

Public Struct STRUTTURA
  b As Byte
  c As Short
  i As Integer
End Struct


Public Sub Main()

 Dim st As New STRUTTURA
 Dim p As Pointer
 
 With st
   .b = 9
   .c = 999
   .i = 99999
 End With

' Assegnamo al "Puntatore" l'indirizzo di memoria della variabile della "Struttura":
 p = Object.Address(st)
   
' Per scorrere all'interno del "Puntatore" lo sommiamo di volta in volta con un valore adeguato ad individuare il tipo di membro della "Struttura".
' Avendo utilizzato la parola chiave "New" nella dichiarazione della variabile della "Struttura", i valori del primo membro inizia al 25° byte (num. 24 di indice) dell'area di memoria occupata dalla "Struttura".
' Procede in questo caso come segue:

' Avanza al byte dell'area di memoria della Struttura [nota 1], occupato dal membro di tipo "Byte"
 Print Byte@(p + 24)

' Rispetto al byte d'indice 24 si deve avanzare di un byte per il necessario "allineamento" del primo e del secondo membro della Struttura; altresì si deve avanzare di un altro byte per giungere al dato-byte iniziale dei 2 byte occupati dal membro di tipo "Short"
 Print Short@(p + (24 + 1 + 1))
' o anche: Print Short@(p + (24 + SizeOf(gb.Short)))

' Rispetto al byte d'indice 24 si deve avanzare di altri due byte per raggiungere il dato-byte iniziale dei 4 byte occupati dal membro di tipo "Integer"
 Print Int@(p + (24 + 1 + 1 + 2))
' o anche: Print Int@(p + (24 + SizeOf(gb.Integer)))

End

Leggere e scrivere nell'area di memoria di una Struttura mediante i Memory Stream

Come sappiamo, una Struttura in sostanza non è altro che un'area riservata di memoria suddivisa al suo interno per settori (membri) di dimensione fra loro non (necessariamente) omogenea.

Lo scopo, quindi, è assegnare tale area di memoria ad un Puntatore, e successivamente attraverso i Memory Stream andare a leggere e/o scrivere in tale area, ossia nella Struttura. Come è evidente, dunque, il processo di lettura e di scrittura all'interno dei membri della Struttura avverrà in modo diverso, atipico rispetto alla normale modalità di lettura/assegnazione di valori che avviene richiamando direttamente i membri della Struttura medesima.

Mostriamo dunque un esempio,pratico:

Public Struct STRUTTURA
  b As Byte
  s As Short
  i As Integer
End Struct


Public Sub Main()

  Dim stru As New STRUTTURA
  Dim st As Stream
  Dim b, j As Byte

' Assegnamo dei valori ai membri della Struttura:
  With stru
    .b = &01
    .s = &1234
    .i = &12345678
  End With

' Ottiene dal Puntatore, ritornato dal Metodo "Object.Address()", uno "Stream" in lettura e scrittura:
  st = Memory Object.Address(stru) For Read Write

' Legge i valori contenuti nell'area di memoria della Struttura, per la sua intera dimensione, alla quale aggiungiamo 24 byte [nota 1], dato che - utilizzando la parola "New" nella dichiarazione dela variabile di tipo "Struttura" ed il Metodo "Object.Address()" - il valore del primo membro è posizionato al 25° byte (indice 24) dello "stream".
' I valori saranno mostrati in rappresentazione esadecimale.
  For j = 0 To 24 + Object.SizeOf(stru) - 1
    Read #st, b
    If j == 24 Then 
      Print "\e[31m\e[1m"; j, Hex(b, 2)
    Else
      Print j, Hex(b, 2)
    Endif
  Next

' Modifica un valore (in questo caso quello del secondo membro, quello di tipo "Short") all'interno della Struttura usando lo "stream" precedentemente creato:
  Seek #st, 24 + SizeOf(gb.Short)
  Write #st, &0987 As Short

  st.Close

' Verifica la scrittura del dato, leggendo ora direttamente il membro di tipo "Short" della Struttura:
   Print "\n\e[0m"; Hex(stru.s, 4)

End

Altro esempio analogo al precedente, ma in sola "Lettura" con i Memory Stream:

Public Struct STRUTTURA
  b As Byte
  c As Short
  i As Integer
End Struct


Public Sub Main()

 Dim st As New STRUTTURA
 Dim sm As Stream
 Dim b As Byte
 Dim c As Short
 Dim i As Integer
 
 With st
   .b = 111
   .c = 2222
   .i = 333333
 End With
   
' Legge i dati presenti nell'area di memoria dell'Oggetto "Struttura" dereferenziando il "Puntatore" mediante la risorsa "Memory Stream", anche in questo caso rispettando, laddove necessario, la regola dell'Allineamento dei dati all'interno della "Struttura":
 sm = Memory Object.Address(st) For Read
' Pone il "Puntatore della risorsa "Stream" al byte di indice 24, ove sono immagazzinati i dati nella "Struttura":
 Seek #sm, 24
 Read #sm, b
' In questo caso rispetta la regola dell'Allineamento dei dati, avanzando di un byte:
 Seek #sm, 26
 Read #sm, c
 Read #sm, i
 sm.Close


' Effettua la verifica:
 Print b
 Print c
 Print i

End

Altro esempio, ma in sola "Scrittura" con i Memory Stream:

Public Struct STRUTTURA
  b As Byte
  s As Short
  i As Integer
End Struct


Public Sub Main()

 Dim stru As New STRUTTURA
 Dim st As Stream
 Dim b As Byte
    
' Ottiene dal Puntatore, ritornato dal Metodo "Object.Address()", uno "Stream" in Scrittura:
 st = Memory Object.Address(stru) For Write
 
' Scrive dei valori nell'area riservata di memoria a cominciare dal byte d'indice offset n. 24 nel rispetto della disposizione dei byte all'interno dell'analoga area di memoria della "Struttura" secondo la regola dell'Allineamento dei dati:
 Seek #st, 24
 Write #st, 111 As Byte
 Write #st, 0 As Byte    ' Avanza di un byte per rispettare la regola dell'Allineamento dei dati
 Write #st, 2222 As Short
 Write #st, 333333 As Integer

 st.Close


' Verifica i valori ora presenti nei tre membri della "Struttura":
 With stru
   Print .b
   Print .s
   Print .i
 End With
 
End


Note

[1] Vedere anche: Ottenere il puntatore di una variabile di tipo Struttura