Configurazione, organizzazione ed impostazione dell'array secondo i sorgenti di Gambas

Da Gambas-it.org - Wikipedia.

Per la creazione di un vettore (array), non v'è la sola e semplice allocazione di memoria per la memorizzazione dei dati contenuti negli cosiddetti elementi del vettore medesimo, ma, essendo anche il vettore un Oggetto di Gambas, si innesca una procedura più complessa che coinvolge più Strutture di dati a livello dei sorgenti di Gambas, e quindi diversi byte di memoria da occupare. [nota 1]

Tali risorse, insomma, servono sia per definire le caratteristiche generali del vettore, sia per memorizzare i dati che esso contiene e riportarne le caratteristiche.

Vediamo, dunque, cosa avviene, appunto, a livello dei sorgenti di Gambas e quali loro risorse in particolare vengono richiamate e usate per creare e gestire un vettore. [nota 2]

La memorizzazione, dunque, dei dati caratterizzanti il vettore e dei dati, e loro caratteristiche (come ad esempio il tipo di valori), contenuti dal vettore, avviene attraverso l'utilizzo di una Struttura, costituita a sua volta da due Strutture:

  • la Struttura chiamata ARRAY e contenuta nel file sorgente ".../main/share/gb_array.h ";
  • la Struttura chiamata OBJECT e contenuta nel file sorgente "...main/gbx/gbx_object.h " dell'Interprete.

Questa unica Struttura, scritta in C, utile per la memorizzazione dei dati in genere del vettore, è chiamata CARRAY ed è contenuta nel file sorgente ".../main/gbx/gbx_c_array.h " dell'Interprete.

Essa è lì così dichiarata:

typedef
       struct {
               OBJECT object;
               int size;
               int count;
               TYPE type;
               void *data;
               int *dim;
               void *ref;
               }
       CARRAY;

Laddove, con riferimento ai membri che ci interessano, abbiamo:

  • OBJECT object, rappresenta la predetta Struttura OBJECT, contenuta nel file sorgente "...main/gbx/gbx_object.h" dell'Interprete. Il primo membro di tale Struttura OBJECT è a sua volta un Puntatore alla Struttura chiamata CLASS e definita nel file sorgente ".../main/gbx/gbx_class.h".
  • int size, è un Intero (Integer) che rappresenta la quantità di memoria in byte del tipo dei valori contenuti nel vettore.
  • int count, è un Intero che rappresenta la quantità di dati/elementi contenuti dal vettore.
  • TYPE type, è un Intero Lungo (Long) che rappresenta il tipo dei dati contenuti nel vettore, secondo i valori definiti nel "Gambas datatypes identifiers" del file sorgente ".../main/share/gambas.h".
  • void *data, è un Puntatore all'area riservata ove sono memorizzati i dati contenuti dal vettore.


Accedere e leggere nella Struttura CARRAY

E' possibile da un progetto Gambas penetrare nella Struttura CARRAY e leggere i dati contenuti nei suoi membri mediante due modalità che mostriamo di seguito.

Utilizzare solo Puntatori

Questa prima modalità prevede l'uso dei soli Puntatori per accedere e muoversi all'interno dell'area di memoria della Struttura CARRAY, e dunque leggere i dati contenuti nei suoi membri.
(L'esempio seguente funziona con sistema a 64-bit !)

Public Sub Main()
 
 Dim bb As Byte[]
 Dim p1, p2, p3 As Pointer
 Dim s As String
 Dim i As Integer
 Dim l As Long

 bb = [11, 22, 33, 44]
   
 p1 = Object.Address(bb)      ' Accede alla Struttura "CARRAY"
  
    p2 = Pointer@(p1)         ' Accede alla Struttura "CLASS"
       p3 = Pointer@(p2 + 24) ' Accede al membro "char *name"
       s = String@(p3)        ' Dereferenzia il membro "char *name"
       Print s                ' Mostra il dato contenuto dal membro "char *name"
  
    i = int@(p1 + 16)         ' Dereferenzia il membro "int size"
    Print i                   ' Mostra il dato contenuto dal membro "int size"
     
    i = int@(p1 + 20)         ' Dereferenzia il membro "int count"
    Print i                   ' Mostra il dato contenuto dal membro "int count"
     
    l = int@(p1 + 24)         ' Dereferenzia il membro "TYPE type"
    Print l                   ' Mostra il dato contenuto dal membro "TYPE type"
     
    p2 = Pointer@(p1 + 32)    ' Accede al membro "void *data"
    For i = 0 To bb.Max       ' Mostra i dati contenuti nell'area di memoria puntata dal membro "void *data"
      Print Byte@(p2 + i),
    Next
     
End


Utilizzare anche una Struttura dichiarata in Gambas

La seconda modalità prevede, invece, l'uso di un Puntatore per il solo accesso all'area di memoria della Struttura, e la successiva assegnazione di tale Puntatore ad una Struttura dichiarata nel progetto Gambas di dimensioni e configurazione simili alla Struttura CARRAY.

Public Struct OBJECTs      ' Riproduce la Struttura annidata 'OBJECT' dichiarata nel file sorgente 'gbx_object.h'
  class_ As Pointer
  ref As Long
End Struct

Public Struct CARRAY      ' Riproduce la Struttura 'CARRAY' dichiarata nel file sorgente 'gbx_c_array.h'
  object_ As Struct OBJECTs
  size As Integer
  count As Integer
  type As Long
  data As Pointer
  dim_ As Pointer
  ref As Pointer
End Struct


Public Sub Main()
 
 Dim bb As Byte[]
 Dim p1 As Pointer
 Dim carr As New CARRAY
 Dim i As Integer
 
 bb = [11, 22, 33, 44, 55]

' Accede alla Struttura "CARRAY":
 p1 = Object.Address(bb)
   
' Assegna l'indirizzo di memoria della Struttura 'CARRAY' all'omonima Struttura scritta in Gambas:
 carr = p1
  
' Mostra i valori presenti nella Struttura dichiarata in Gambas:
 With carr
   Print "Byte occupati dal tipo di valore dell'array: "; .size; " byte"
   Print "Quantità di elementi presenti nell'array:    "; .count
   Print "Tipo dei valori contenuti dall'array         "; .type
   Print "Il vettore contiene i seguenti valori:"
   For i = 0 to bb.Max
     Print Byte@(.data + i),
   Next       
 End With
   
End


Note

[1] Un oggetto Gambas non è soltanto un'astrazione, un elemento generico di un Classe, né soltanto un'immagine di un aggeggio (widget) virtuale. Esso è innanzitutto memoria allocata, debitamente e coerentemente, secondo i tipi dichiarati in alcune Strutture, previste dai sorgenti di Gambas, che lo caratterizzano come un Oggetto ben determinato appartenente ad una Classe specifica.

[2] La descrizione esposta in questa pagina vale anche per le matrici annidate: matrice[rig, col].