Emulare in Gambas la funzione memcpy() di C

Da Gambas-it.org - Wikipedia.
(Reindirizzamento da Emulare la funzione memcpy() di C)

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