Differenze tra le versioni di "Assegnare ad un vettore i valori contenuti da un'area di memoria puntata da un Puntatore"

Da Gambas-it.org - Wikipedia.
Riga 1: Riga 1:
Per assegnare ad un vettore i valori contenuti da un'area di memoria puntata da un ''Puntatore'', è possibile adottare almeno due modalità.
+
Per assegnare ad un vettore i valori contenuti da un'area di memoria puntata da un ''Puntatore'', è possibile adottare alcune modalità.
  
  
Riga 13: Riga 13:
 
   Dim b As Byte
 
   Dim b As Byte
 
    
 
    
  <FONT Color=gray>' ''Ai fini di questo esempio andiamo a riempire di valori un'area di memoria riservata, che sarà puntata da un Puntatore qui ritornato:''</font>
+
  <FONT Color=gray>' ''Ai fini di questo esempio riempie di valori un'area di memoria riservata, che sarà puntata da un Puntatore qui ritornato:''</font>
 
   p = Riempie_Puntatore()
 
   p = Riempie_Puntatore()
 
        
 
        
  <FONT Color=gray>' ''Assegnamo agli elementi del vettore i valori presenti nell'area di memoria allocata:''</font>
+
  <FONT Color=gray>' ''Assegna agli elementi del vettore i valori presenti nell'area di memoria allocata:''</font>
 
   For i = 0 To 7
 
   For i = 0 To 7
 
     bb[i] = byte@(p + i)
 
     bb[i] = byte@(p + i)
 
   Next
 
   Next
 
      
 
      
  <FONT Color=gray>' ''Verifichiamo infine in console il risultato del precedente l'assegnamento:''</font>
+
  <FONT Color=gray>' ''Verifica infine in console il risultato del precedente l'assegnamento:''</font>
 
   For Each b In bb
 
   For Each b In bb
 
     Print b
 
     Print b
Riga 29: Riga 29:
 
   
 
   
 
   
 
   
  <FONT Color=gray>' ''Ci serviamo di questa funzione solo per riempire di valori un'area di memoria riservata da utilizzare nella routine principale.''</font>
+
  <FONT Color=gray>' ''Si serve di questa funzione solo per riempire di valori un'area di memoria riservata da utilizzare nella routine principale.''</font>
 
  '''Private''' Function Riempie_Puntatore() As Pointer
 
  '''Private''' Function Riempie_Puntatore() As Pointer
 
    
 
    
 
   Dim vet As Byte[] = [1, 2, 3, 4, 5, 6, 7, 8]
 
   Dim vet As Byte[] = [1, 2, 3, 4, 5, 6, 7, 8]
 
    
 
    
  <FONT Color=gray>' ''Ritorniamo alla routine principale l'indirizzo dell'area di memoria del vettore, nella quale sono contenuti i dati:''</font>
+
  <FONT Color=gray>' ''Ritorna alla routine principale l'indirizzo dell'area di memoria del vettore, nella quale sono contenuti i dati:''</font>
 
   Return vet.Data
 
   Return vet.Data
 
    
 
    

Versione delle 21:32, 3 nov 2021

Per assegnare ad un vettore i valori contenuti da un'area di memoria puntata da un Puntatore, è possibile adottare alcune modalità.


Uso delle funzioni di Gambas di dereferenziazione dei Puntatori

La prima modalità prevede di assegnare ad ogni elemento del vettore i valori dell'area di memoria riservata, puntata dal Puntatore, dereferenziando man mano il Puntatore medesimo.

Mostriamo un semplice esempio pratico:

Public Sub Main()
 
 Dim p As Pointer
 Dim i as integer
 Dim bb As New Byte[8]
 Dim b As Byte
 
' Ai fini di questo esempio riempie di valori un'area di memoria riservata, che sarà puntata da un Puntatore qui ritornato:
  p = Riempie_Puntatore()
      
' Assegna agli elementi del vettore i valori presenti nell'area di memoria allocata:
  For i = 0 To 7
    bb[i] = byte@(p + i)
  Next
   
' Verifica infine in console il risultato del precedente l'assegnamento:
  For Each b In bb
    Print b
  Next
  
End


' Si serve di questa funzione solo per riempire di valori un'area di memoria riservata da utilizzare nella routine principale.
Private Function Riempie_Puntatore() As Pointer
 
 Dim vet As Byte[] = [1, 2, 3, 4, 5, 6, 7, 8]
 
' Ritorna alla routine principale l'indirizzo dell'area di memoria del vettore, nella quale sono contenuti i dati:
  Return vet.Data
 
End


Leggendo con il Metodo ".Read( )" del vettore i dati contenuti da un'area di memoria, puntata da un Puntatore aperto in lettura con i "Memory Stream"

In questo caso si provvederà a gestire in lettura con il Metodo ".Read( )" del vettore i dati contenuti nell'indirizzo dell'area di memoria, puntata da un Puntatore aperto in lettura con i "Memory Stream". [nota 1]
Questo è senz'altro la modalità più veloce.

Ne mostriamo un esempio:

Public Sub Main()
 
 Dim p As Pointer
 Dim bb As Byte[]
 Dim st As Stream
 Dim b As Byte
 
' Ai fini di questo esempio andiamo a riempire di valori un'area di memoria riservata, che sarà puntata da un Puntatore qui ritornato:
  p = Riempie_Puntatore()   
  
' Crea in lettura una variabile "Stream" dal Puntatore sopra ritornato:
  st = Memory p For Read
  
' Con il Metodo ".Read()" il vettore legge e memorizza i dati presenti nell'area di memoria puntata dal Puntatore sopra restituito:
  bb.Read(st, 0, bb.Count)
  
  st.Close
  p = 0
  
' Verifichiamo infine in console il risultato:
  For Each b In bb
    Print b
  Next
        
End


Private Function Riempie_Puntatore() As Pointer
 
 Dim vet As Byte[] = [1, 2, 3, 4, 5, 6, 7, 8]
 
' Ritorniamo alla routine principale l'indirizzo dell'area di memoria del vettore, nella quale sono contenuti i dati:
  Return vet.Data
 
End


Scrivendo con i "Memory Stream" nell'indirizzo dell'area di memoria del vettore, nella quale sono contenuti i dati

In questo caso si provvederà a scrivere i valori, contenuti da un'area di memoria allocata, nell'indirizzo, restituito dalla proprietà ".Data" del vettore, dell'area di memoria del vettore, nella quale sono contenuti i dati. [nota 1]

Ne mostriamo un esempio:

Public Sub Main()
 
 Dim p As Pointer
 Dim bb As Byte[]
 Dim i As Integer
 Dim st As Stream
 Dim b As Byte
  
' Ai fini di questo esempio andiamo a riempire di valori un'area di memoria riservata, che sarà puntata da un Puntatore qui ritornato:
  p = Riempie_Puntatore()   
  
' Andiamo a scrivere i valori, contenuti nell'area di memoria puntata dal Puntatore ritornato:
  st = Memory bb.Data For Write
  For i = 0 To bb.Max
    Write #st, Byte@(p + i) As Byte
  Next
  
  st.Close
  p = 0
  
' Verifichiamo infine in console il risultato:
  For Each b In bb
    Print b
  Next
        
End


Private Function Riempie_Puntatore() As Pointer
 
 Dim vet As Byte[] = [1, 2, 3, 4, 5, 6, 7, 8]
 
' Ritorniamo alla routine principale l'indirizzo dell'area di memoria del vettore, nella quale sono contenuti i dati:
  Return vet.Data
 
End


Uso della funzione esterna memcpy() di C

Possiamo anche utilizzare la funzione esterna memcpy() di C, richiamando la libreria libc.so.6 . Mostriamo un semplice esempio pratico:

Library "libc:6"

' void *memcpy (void * __dest, const void * __src, size_t __n)
' Copy N bytes of SRC to DEST.
Private Extern memcpy(__dest As Pointer, __src As Pointer, __n As Long) As Pointer


Public Sub Main()
 
 Dim p As Pointer
 Dim b As Byte
 Dim bb As New Byte[8]
 
' Ai fini di questo esempio andiamo a riempire di valori un'area di memoria riservata, che sarà puntata da un Puntatore qui ritornato:
  p = Riempie_Puntatore()  
   
' Con la funzione esterna "memcpy()" copiamo nel vettore gli 8 valori presenti nell'area di memoria allocata:
  memcpy(bb.Data, p, 8)
   
' Verifichiamo in console l'assegnamento:
  For Each b In bb
    Print b
  Next
  
  p = 0
  
End
 
 
Private Function Riempie_Puntatore() As Pointer
 
 Dim vet As Byte[] = [1, 2, 3, 4, 5, 6, 7, 8]
 
' Ritorniamo alla routine principale l'indirizzo dell'area di memoria del vettore, nella quale sono contenuti i dati:
  Return vet.Data
 
End

Assegnando il Puntatore al membro Data della Struttura CARRAY dei sorgenti di Gambas

Un'altra modalità, più complessa, è quella di assegnare il Puntatore al membro data della Struttura CARRAY dei sorgenti di Gambas.

La Struttura CARRAY presente nel file header gbx_c_array.h dei sorgenti di Gambas è così definita:

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

laddove in particolare il membro:

  • size è un intero che rappresenta la dimensione dei valori contenuti dal vettore (ossia è il tipo di valori del vettore);
  • count' è un intero che rappresenta il numero di elementi costituenti il vettore;
  • data è un Puntatore all'area di memoria riservata che contiene i dati contenuti dal vettore.

Pertanto, nel codice che appronteremo, bisognerà:
1) cambiare, qualora il numero di elementi del vettore sia diverso dalla dimensione dell'area puntata dal Puntatore (tenuto conto ovviamente dal tipo di valori), il valore presente nel membro count, assegnandogli il valore corrispondente al nuovo numero di elementi che il vettore dovrà possedere;
2) cambiare il valore del Puntatore all'area di memoria dei dati presente nel membro data, assegnando il nuovo Puntatore.

Se si sta scrivendo un'applicazione in ambiente grafico (come nell'esempio che segue), è opportuno, al fine di evitare errori di memoria, chiudere il programma con la funzione esterna risolutiva di C: exit() .

Mostriamo di seguito un esempio pratico:

Public Sub Main()
 
 Dim p, pbb As Pointer
 Dim bb As New Byte[8]
 Dim st As Stream
 Dim b, n As Byte
 
' Invoca la funzione per creare e istanziare un'area riservata di memoria:
 p = AllocaMemoria(8)
 
' Accediamo alla "Struttura" interna dell'oggetto "array" (il vettore dichiarato "bb") di Gambas:
 pbb = Object.Address(bb)
  
' Accediamo al membro "data" della predetta "Struttura" interna del vettore "bb":
 st = Memory pbb + 32 For Write
 
' Assegnamo il nuovo "indirizzo di memoria" al membro "data" della "Struttura" interna del vettore "bb":
 Write #st, p As Pointer
 st.Close
 Free(p)
  
' Verifichiamo i valori presenti nel vettore "bb":
 For each b in bb
   Print b
 Next
  
End


Private Function AllocaMemoria(n As Integer) As Pointer
 
 Dim po As Pointer
 Dim sr As Stream
 Dim i As Integer
 
 po = Alloc(SizeOf(gb.Byte), n)
 
 sr = Memory po For Write
 For i = 1 To 8
   Write #sr, i * 11 As Byte
 Next
 
 Return po
  
End



Note

[1] Vedasi anche la seguente pagina della WIKI: Leggere e scrivere in un vettore mediante i Memory Stream