Creare con i Memory Stream un'area di memoria simile ad una Struttura avente come membro un'altra Struttura
Come si sa, una Struttura non è altro, in fin dei conti, che un'area riservata di memoria, avente una dimensione pari al tipo di dati al quale appartiene ciascun membro della Struttura medesima compresi gli eventuali allineamenti dei membri.
E' dunque possibile creare mediante i Memory Stream un'area di memoria analoga ad una Struttura. In questa pagina vederemo come realizzare una semplice Struttura innestata, ossia una Struttura in cui almeno un suo membro è un'altra Struttura.
Va precisato che in Gambas, in via generale, il membro di una Struttura (innestata), contenente il riferimento ad un'altra Struttura (innesto), non contiene altro che l'indirizzo di memoria (e pertanto sarà un dato di tipo Puntatore) di detta sub-Struttura innesto. Bisognerà ricordare, dunque, che nell'area di memoria della "simil-Struttura", che andiamo a costruire con i Memory Stream, ove inserire il riferimento alla sub-Struttura (cioè della Struttura innesto che è membro della Struttura principale innestata), dovremo scrivere l'indirizzo di memoria di questa sub-Struttura innesto.
Dunque, come esempio, l'obiettivo è quello di costruire una Struttura (innestata), comprensiva di sub-Struttura "innesto", come quella che di seguito avremmo in Gambas:
Public Struct Struttura_Innesto ' Struttura secondaria che è richiamata (rappresentata) da almeno un membro di un'altra Struttura (principale) b As Byte sh As Short i As Integer End Struct Public Struct STRUTTURA_INNESTATA ' Struttura principale che contiene almeno un membro che è un'altra Struttura b As Byte sh As Short i As Integer subStru As Struct Struttura_Innesto ii As Integer End Struct
Tale Struttura innestata, compresa quella innesto, verrà con i Memory Stream così sviluppata:
Public Sub Main() Dim struttura, substruttura, legge_Pointer As Pointer ' «struttura» rappresenta la "Struttura-Innestata", mentre «substruttura» rappresenta la "Struttura-Innesto" Dim st, subs As Stream Dim legge_Byte, sub_b As Byte Dim legge_Short, sub_sh As Short Dim legge_Integer, sub_i As Integer ' Allochiamo la necessaria memoria coerente con la somma delle dimensioni dei vari dati componenti le due "Strutture" anche tenuto conto degli eventuali "allineamenti dei dati": struttura = Alloc(SizeOf(gb.Byte), 24) substruttura = Alloc(SizeOf(gb.Byte), 8) ' Scriviamo dei valori all'interno dell'area di memoria riservata della "Struttura" principale, quella "innestata", ovviamente sulla base della quantità di memoria occupata dai tipi di dati previsti e degli eventuali "allineamenti dei dati". ' Cominciamo con l'assegnare dei valori alla sub-Struttura, ossia l'innesto: subs = Memory substruttura For Write Write #subs, 44 As Byte Seek #subs, 2 Write #subs, 444 As Short Write #subs, 44444 As Integer subs.Close st = Memory struttura For Read Write ' Scriviamo i dati nella "Struttura" principale, quella "innestata": Write #st, 99 As Byte Seek #st, 2 Write #st, 999 As Short Write #st, 99999 As Integer ' Ora creiamo il riferimento alla Struttura "innesto", scrivendo l'indirizzo di memoria: Write #st, substruttura As Pointer ' Poiché il puntatore occupa 8 byte, ci spostiamo al byte n. 16 (ossia il 17°): Seek #st, 16 Write #st, 999999 As Integer ' Come verifica del nostro esperimento, leggiamo i dati in base al tipo che è stato assegnato: Seek #st, 0 Read #st, legge_Byte Print "struttura: "; legge_Byte Seek #st, 2 Read #st, legge_Short Print "struttura: "; legge_Short Read #st, legge_Integer Print "struttura: "; legge_Integer ' Ora "trasferiamo" la nostra lettura nell'area di memoria della sub-Struttura "innesto", acquisendo innanzitutto il suo indirizzo di memoria: Read #st, legge_Pointer subs = Memory legge_Pointer For Read Read #subs, sub_b Print " substruttura: "; sub_b Seek #subs, 2 Read #subs, sub_sh Print " substruttura: "; sub_sh Read #subs, sub_i Print " substruttura: "; sub_i subs.Close ' Torniamo a leggere i dati (l'ultimo) nella Struttura principale (quella "innestata"). ' Poiché il puntatore occupa 8 byte, ci spostiamo al byte n. 16 (ossia il 17°): Seek #st, 16 Read #st, legge_Integer Print "struttura: "; legge_Integer st.Close Free(substruttura) Free(struttura) End