Differenze tra le versioni di "Emulare in Gambas la funzione memcpy() di C"

Da Gambas-it.org - Wikipedia.
 
(Una versione intermedia di uno stesso utente non è mostrata)
Riga 19: Riga 19:
 
  '''Public''' Sub Main()
 
  '''Public''' Sub Main()
 
    
 
    
 +
  Dim s As String = "abcde"
 
   Dim p As Pointer
 
   Dim p As Pointer
 
   Dim bb As Byte[]
 
   Dim bb As Byte[]
Riga 24: Riga 25:
 
   Dim i As Integer
 
   Dim i As Integer
 
    
 
    
  p = <FONT Color=gray>Funzione_che_restituisce_un_Puntatore</font>()
+
<FONT Color=gray>' ''Alloca un'area di memoria, nella quale scrive i dati della stringa contenuta nella variabile "s":''</font>
 +
  p = Alloc(s)
 
    
 
    
  bb = New Byte[<FONT Color=gray>''numero_conosciuto''</font>]
+
<FONT Color=gray>' ''Crea un Oggetto vettore, avente una quantità di elementi pari ai caratteri costituenti la strings contenuta nella variabile "s":''</font>
 +
  bb = New Byte[s.Len]
 
    
 
    
 
   st = Memory p For Read
 
   st = Memory p For Read
  <FONT Color=gray>' ''Legge i dati dallo "stream", che rappresenta l'area di memoria allocata puntata dal Puntatore "p", e li copia nel vettore "bb":''</font>
+
  <FONT Color=gray>' ''Legge i dati dallo "stream", che rappresenta l'area di memoria allocata, puntata dal Puntatore "p", e li copia nel vettore "bb":''</font>
 
   bb.Read(st, 0, bb.Count)
 
   bb.Read(st, 0, bb.Count)
 
   st.Close
 
   st.Close
 +
 +
<FONT Color=gray>' ''Dealloca l'area precedentemente riservata e si assicura che il "Puntatore" non punti ad un indirizzo rilevante di memoria:''</font>
 +
  Free(p)
 +
  p = 0
 
   
 
   
 
  <FONT Color=gray>' ''Verifica il risultato, mostrando i singoli valori-byte, salvati nell'area di memoria del vettore di tipo "Byte[]":''</font>
 
  <FONT Color=gray>' ''Verifica il risultato, mostrando i singoli valori-byte, salvati nell'area di memoria del vettore di tipo "Byte[]":''</font>
 
   For i = 0 To bb.Max
 
   For i = 0 To bb.Max
     Print i, Hex(bb[i], 2)
+
     Print i, Hex(bb[i], 2), Chr(bb[i])
 
   Next
 
   Next
 
    
 
    

Versione attuale delle 03:47, 15 apr 2023

La funzione di memcpy() del linguaggio C copia un numero di dati (byte), specificato dal suo 3° argomento, da un'area di memoria riservata ad un'altra.

Per emulare in Gambas il comportamento di questa funzione, si possono adottare varie modalità.

Uso di due vettori di tipo "Byte[]"

La più semplice è quella di utilizzare - se possibile - due vettori di tipo "Byte[]", giacché i vettori sono in buona sostanza delle aree di memoria riservate.
In particolare si utilizzerà il Metodo ".Copy()" del vettore contenente i dati da copiare nell'altro vettore.

Dim bb1, bb2 As New Byte[...]

......

bb2 = bb1.Copy(0, bb1.Count)

L'uso del Metodo ".Copy()" copierà i dati di un vettore nell'altro, mantenendo però tali vettori come due Oggetti "distinti", o meglio, vettori che puntano ciascuno ad aree di memoria riservata "diverse".

Uso dei Memory Stream e di un vettore di tipo "Byte[]"

Qualora si abbia una variabile di tipo Puntatore, che punta a un'area di memoria riservata contenente dati da copiare in un'altra area di memoria riservata (e dunque non sia abbia per qualche motivo la disponibilità di due vettori di tipo "Byte[]"), il modo più semplice di copiatura è quello di utilizzare la risorsa dei Memory Stream e un vettore di tipo "Byte[]".

Più in particolare si utilizzeranno i Memory Stream per leggere i dati presenti nell'area di memoria puntata dal Puntatore. In tal caso è assolutamente necessario conoscere la quantità di dati contenuti dalla predetta area di memoria puntata dal Puntatore.

Public Sub Main()
 
 Dim s As String = "abcde"
 Dim p As Pointer
 Dim bb As Byte[]
 Dim st As Stream
 Dim i As Integer
 
' Alloca un'area di memoria, nella quale scrive i dati della stringa contenuta nella variabile "s":
 p = Alloc(s)
 
' Crea un Oggetto vettore, avente una quantità di elementi pari ai caratteri costituenti la strings contenuta nella variabile "s":
 bb = New Byte[s.Len]
 
 st = Memory p For Read
' Legge i dati dallo "stream", che rappresenta l'area di memoria allocata, puntata dal Puntatore "p", e li copia nel vettore "bb":
 bb.Read(st, 0, bb.Count)
 st.Close

' Dealloca l'area precedentemente riservata e si assicura che il "Puntatore" non punti ad un indirizzo rilevante di memoria:
 Free(p)
 p = 0

' Verifica il risultato, mostrando i singoli valori-byte, salvati nell'area di memoria del vettore di tipo "Byte[]":
 For i = 0 To bb.Max
   Print i, Hex(bb[i], 2), Chr(bb[i])
 Next
 
End

Caso in cui non si conosca la quantità di dati da copiare

Qualora il numero di dati da copiare non sia conosciuto, allora si potrà assegnare il Puntatore (ossia l'indirizzo di memoria dell'area di memoria riservata contenente i dati da copiare) al membro data della Struttura CARRAY dei sorgenti di Gambas afferenti all'Oggetto Array.
Per detto argomento vedere questo paragrafo della Wiki: Assegnando il Puntatore al membro Data della Struttura CARRAY dei sorgenti di Gambas


Leggendo e scrivendo dato per dato con un ciclo

Una terza modalità, meno veloce rispetto alla precedente, è quella di leggere dato per dato da una variabile di tipo Puntatore e di scriverlo nell'area di memoria riservata attraverso un ciclo. Ciò può essere compiuto sia con un secondo Puntatore o di nuovo con un vettore di tipo "Byte[]".
Anche in questa modalità è necessario conoscere la quantità di dati da copiare.

Nel caso si utilizzino due Puntatori (uno dal quale leggere i dati, l'altro dove scriverli), la scrittura dei dati nella seconda variabile di tipo Puntatore ovviamente potrà avvenire in modo esclusivo attraverso i Memory Stream.



Riferimenti