Differenze tra le versioni di "Memcpy ()"

Da Gambas-it.org - Wikipedia.
 
(11 versioni intermedie di uno stesso utente non sono mostrate)
Riga 1: Riga 1:
 
La funzione della libreria di C
 
La funzione della libreria di C
 
  ''void *'''memcpy'''(void *__restrict __dest, const void *__restrict __src, size_t __n)''
 
  ''void *'''memcpy'''(void *__restrict __dest, const void *__restrict __src, size_t __n)''
copia ''n'' caratteri da un'area di memoria ''str2'' ad un'altra area di memoria ''str1'', entrambe puntate da due variabili di tipo ''Puntatore''.
+
copia ''n'' caratteri da un'area di memoria ''__src'' ad un'altra area di memoria ''__dest'', entrambe puntate da due variabili di tipo ''Puntatore''.
  
 
Va ricordato che per la variabile di tipo ''Puntatore'' del primo parametro (ossia: ''void *__restrict __dest'') deve essere <SPAN Style="text-decoration:underline">sempre</span> ''allocata'' un'area di memoria di quantità adeguata.
 
Va ricordato che per la variabile di tipo ''Puntatore'' del primo parametro (ossia: ''void *__restrict __dest'') deve essere <SPAN Style="text-decoration:underline">sempre</span> ''allocata'' un'area di memoria di quantità adeguata.
Riga 8: Riga 8:
 
Volendola utilizzare in Gambas, bisognerà dichiararla con ''Extern'', nonché bisognerà dichiarare la libreria di C: ''libc.so.6'', nella quale la funzione è contenuta:
 
Volendola utilizzare in Gambas, bisognerà dichiararla con ''Extern'', nonché bisognerà dichiarare la libreria di C: ''libc.so.6'', nella quale la funzione è contenuta:
 
  Private <FONT color=#B22222>Extern memcpy</font>(__dest As Pointer, __src As Pointer, __n As Long) In "<FONT color=#B22222>libc:6</font>"
 
  Private <FONT color=#B22222>Extern memcpy</font>(__dest As Pointer, __src As Pointer, __n As Long) In "<FONT color=#B22222>libc:6</font>"
 
  
  
Riga 18: Riga 17:
 
  Private Extern <FONT color=#B22222>memcpy</font>(__dest As Pointer, __src As Pointer, __n As Long)
 
  Private Extern <FONT color=#B22222>memcpy</font>(__dest As Pointer, __src As Pointer, __n As Long)
 
   
 
   
  '''Public''' Sub Main()
+
   
 +
Public Sub Main()
 
   
 
   
 
   Dim p1, p2 As Pointer
 
   Dim p1, p2 As Pointer
 
   Dim num As Integer
 
   Dim num As Integer
 
    
 
    
  num = 999
+
  num = 999
 
   
 
   
  p1 = VarPtr(num)
+
  p1 = VarPtr(num)
  p2 = Alloc(SizeOf(gb.Integer), 1)
+
  p2 = Alloc(SizeOf(gb.Integer), 1)
 
    
 
    
  <FONT color=#B22222>memcpy</font>(p2, p1, SizeOf(gb.Integer))
+
  <FONT color=#B22222>memcpy</font>(p2, p1, SizeOf(gb.Integer))
 
    
 
    
  Print Int@(p2)
+
  Print Int@(p2)
 
   
 
   
  Free(p2)
+
  Free(p2)
 
   
 
   
  '''End'''
+
  End
  
  
Riga 46: Riga 46:
 
   
 
   
 
   
 
   
  '''Public''' Sub Main()
+
  Public Sub Main()
 
   
 
   
 
   Dim dest As Pointer
 
   Dim dest As Pointer
 
   Dim src As String = "Questa è una prova con la funzione 'memcpy()'."
 
   Dim src As String = "Questa è una prova con la funzione 'memcpy()'."
 
   Dim i As Integer
 
   Dim i As Integer
 +
 
 +
  i = Len(src)
 
    
 
    
  i = Len(src)
+
<FONT Color=gray>' ''Allochiamo un'area di memoria adeguata per contenere tutti i valori costituenti i caratteri della stringa:''</font>
 
+
  dest = Alloc(SizeOf(gb.Byte), i)
  dest = Alloc(SizeOf(gb.Byte), i)
 
 
      
 
      
  <FONT color=#B22222>memcpy</font>(dest, src, i)
+
<FONT Color=gray>' ''Il valore numerico del 3° argomento sarà aumentato di un'unità, affinché con la funzione nativa di dereferenziazione non si vada oltre i valori corrispondenti ai caratteri della stringa copiata.''</font>
 +
  <FONT color=#B22222>memcpy</font>(dest, src, CLong(i + 1))
 
      
 
      
  Print "Dopo memcpy, " & Quote("dest") & ":\n"; String@(dest)
+
  Print "Dopo memcpy, " & Quote("dest") & ":\n"; String@(dest)
 
    
 
    
  Free(dest)
+
<FONT Color=gray>' ''Liberiamo l'area di memoria precedentemente allocata:''</font>
 +
  Free(dest)
 +
<FONT Color=gray>' ''Ci assicuriamo comunque che il Puntatore non punti ad alcuna cella importante di memoria:''</font>
 +
  dest = 0
 
    
 
    
  '''End'''
+
  End
  
  
Riga 71: Riga 76:
 
  <FONT Color=gray>' ''void *memcpy (void *__restrict __dest, const void *__restrict __src, size_t __n)''
 
  <FONT Color=gray>' ''void *memcpy (void *__restrict __dest, const void *__restrict __src, size_t __n)''
 
  ' ''Copy N bytes of SRC to DEST.''</font>
 
  ' ''Copy N bytes of SRC to DEST.''</font>
  Private Extern memcpy(__dest As Pointer, __src As String, __n As Long) As Pointer
+
  Private Extern memcpy(__dest As Pointer, __src As Pointer, __n As Long) As Pointer
 
   
 
   
 
   
 
   
  '''Public''' Sub Main()
+
  Public Sub Main()
 
    
 
    
 
   Dim a, b As String
 
   Dim a, b As String
Riga 80: Riga 85:
 
   Dim i As Integer
 
   Dim i As Integer
 
    
 
    
  a = "aaaa"
+
  a = "aaaa"
  b = "bbbb"
+
  b = "bbbb"
 +
 
 +
  i = Len(a)
 +
 
 +
<FONT Color=gray>' ''Allochiamo un'area di memoria adeguata per contenere tutti i valori costituenti i caratteri della stringa:''</font>
 +
  dest = Alloc(SizeOf(gb.Byte), i)
 
      
 
      
  <FONT Color=gray>' ''Allochiamo una sufficiente area di memoria ove saranno memorizzati in successione i dati delle due variabili stringa:''</font>
+
  <FONT Color=gray>' ''Copiamo nell'area di memoria l'intero numero di dati contenuti dalla variabile stringa "a".
  dest = Alloc(SizeOf(gb.Byte), 16)
+
' ''Il valore numerico del 3° argomento sarà aumentato di un'unità, affinché con la funzione nativa di dereferenziazione non si vada oltre i valori corrispondenti ai caratteri della stringa copiata.''</font>
 +
  memcpy(dest, a, CLong(i + 1))
 
      
 
      
  i = Len(a)
+
<FONT Color=gray>' ''Poiché dobbiamo memorizzare successivamente anche i dati presenti nella variabile stringa "b", è necessario spostarci all'interno dell'area di memoria allocata di un numero di byte pari alla dimensione della stringa contenuta dalla variabile "a":''</font>
 +
  dest += i
 
      
 
      
<FONT Color=gray>' ''Copiamo nell'area di memoria l'intero numero di dati contenuti dalla variabile stringa "a":''</font>
+
  i = Len(b)
  memcpy(dest, a, i)
 
   
 
<FONT Color=gray>' ''Poiché dobbiamo memorizzare successivamente anche i dati presenti nella variabile stringa "b",''
 
' ''è necessario spostarci all'interno dell'area di memoria allocata di un numero di byte pari alla dimensione della stringa:''</font>
 
  dest += i
 
   
 
  i = Len(b)
 
 
      
 
      
 
  <FONT Color=gray>' ''Copiamo nell'area di memoria, dopo i dati già copiati dalla variabile stringa "a", l'intero numero di dati contenuti dalla variabile stringa "b":''</font>
 
  <FONT Color=gray>' ''Copiamo nell'area di memoria, dopo i dati già copiati dalla variabile stringa "a", l'intero numero di dati contenuti dalla variabile stringa "b":''</font>
  memcpy(dest, b, i)
+
  memcpy(dest, b, CLong(i + 1))
 
      
 
      
  <FONT Color=gray>' ''Poiché il punatore interno dell'area di memoria riservata è spostato in avanti rispetto al primo byte dell'area medesima,''
+
  <FONT Color=gray>' ''Poiché il puntatore interno dell'area di memoria riservata è spostato in avanti rispetto al primo byte dell'area medesima, è necessario riportarlo dunque all'inizio:''</font>
' ''è necessario riportare appunto all'inizio il puntatore:''</font>
+
  dest -= i
  dest -= i
 
 
      
 
      
 
  <FONT Color=gray>' ''Dereferenziamo il Puntatore all'area di memoria allocata per vederne il contenuto in console:''</font>
 
  <FONT Color=gray>' ''Dereferenziamo il Puntatore all'area di memoria allocata per vederne il contenuto in console:''</font>
  Print String@(dest)
+
  Print String@(dest)
 
      
 
      
 
  <FONT Color=gray>' ''Liberiamo l'area di memoria precedentemente allocata:''</font>
 
  <FONT Color=gray>' ''Liberiamo l'area di memoria precedentemente allocata:''</font>
  Free(dest)
+
  Free(dest)
+
  <FONT Color=gray>' ''Ci assicuriamo comunque che il Puntatore non punti ad alcuna cella importante di memoria:''</font>
  <FONT Color=gray>' ''Ci asicuriamo comunque che il Puntatore non punti ad alcuna cella di memoria:''</font>
+
  dest = 0
  dest = 0
 
 
    
 
    
  '''End'''
+
  End
  
  
Riga 121: Riga 124:
 
  <FONT Color=gray>' ''void *memcpy (void *__restrict __dest, const void *__restrict __src, size_t __n)''
 
  <FONT Color=gray>' ''void *memcpy (void *__restrict __dest, const void *__restrict __src, size_t __n)''
 
  ' ''Copy N bytes of SRC to DEST.''</font>
 
  ' ''Copy N bytes of SRC to DEST.''</font>
  Private Extern memcpy(__dest As Pointer, __src As String, __n As Long) As Pointer
+
  Private Extern memcpy(__dest As Pointer, __src As Pointer, __n As Long) As Pointer
 
   
 
   
 
   
 
   
  '''Public''' Sub Main()
+
  Public Sub Main()
 
    
 
    
 
   Dim a, b As String
 
   Dim a, b As String
Riga 130: Riga 133:
 
   Dim ia, ib As Integer
 
   Dim ia, ib As Integer
 
    
 
    
  a = "aaaa"
+
  a = "aaaa"
  b = "bbbb"
+
  b = "bbbb"
 
      
 
      
 
  <FONT Color=gray>' ''Attribuiamo un sufficiente numero di elementi al vettore, ossia allochiamo una sufficiente area di memoria per il vettore medesimo:''</font>
 
  <FONT Color=gray>' ''Attribuiamo un sufficiente numero di elementi al vettore, ossia allochiamo una sufficiente area di memoria per il vettore medesimo:''</font>
  dest = New Byte[16]
+
  dest = New Byte[16]
 
      
 
      
  ia = Len(a)
+
  ia = Len(a)
 
      
 
      
 
  <FONT Color=gray>' ''Copiamo nell'area di memoria l'intero numero di dati contenuti dalla variabile stringa "a":''</font>
 
  <FONT Color=gray>' ''Copiamo nell'area di memoria l'intero numero di dati contenuti dalla variabile stringa "a":''</font>
  memcpy(dest.Data, a, ia)
+
  memcpy(dest.Data, a, CLong(ia + 1))
 
    
 
    
  ib = Len(b)
+
  ib = Len(b)
 
      
 
      
 
  <FONT Color=gray>' ''Copiamo nell'area di memoria del vettore, destinata a memorizzare i propri dati, l'intero numero di dati contenuti dalla variabile stringa "b".
 
  <FONT Color=gray>' ''Copiamo nell'area di memoria del vettore, destinata a memorizzare i propri dati, l'intero numero di dati contenuti dalla variabile stringa "b".
 
  ' ''L'area di memoria di memorizzazione dei dati del vettore è individuata dal suo indirizzo ritornato dalla proprietà ".Data" del vettore medesimo.
 
  ' ''L'area di memoria di memorizzazione dei dati del vettore è individuata dal suo indirizzo ritornato dalla proprietà ".Data" del vettore medesimo.
 
  ' ''Ci spostiamo di 4 byte avanti nell'area di memoria del vettore, al fine di non sovrascrivere i dati già copiati precedentemente della stringa "a":''</font>
 
  ' ''Ci spostiamo di 4 byte avanti nell'area di memoria del vettore, al fine di non sovrascrivere i dati già copiati precedentemente della stringa "a":''</font>
  memcpy(bb.Data + ia, b, ib)
+
  memcpy(dest.Data + ia, b, CLong(ib + 1))
 
    
 
    
 
  <FONT Color=gray>' ''Mostriamo in console i dati "utili" (ossia in questo caso quelli rappresentanti la copia delle due stringhe originarie) contenuti dal vettore:''</font>
 
  <FONT Color=gray>' ''Mostriamo in console i dati "utili" (ossia in questo caso quelli rappresentanti la copia delle due stringhe originarie) contenuti dal vettore:''</font>
  Print dest.ToString(0, ia + ib)
+
  Print dest.ToString(0, ia + ib)
 
    
 
    
 
  <FONT Color=gray>' ''...o magari leggendo con la funzione di dereferenziazione di Gambas direttamente nell'area di memoria dei dati memorizzati dal vettore:''</font>
 
  <FONT Color=gray>' ''...o magari leggendo con la funzione di dereferenziazione di Gambas direttamente nell'area di memoria dei dati memorizzati dal vettore:''</font>
  Print String@(dest.Data)
+
  Print String@(dest.Data)
 
    
 
    
  '''End'''
+
  End
  
 +
 +
===Sostituire un carattere all'interno di una stringa===
 +
In quest'altro caso sostituiremo un carattere all'interno di una stringa:
 +
 +
Library "libc:6"
 +
 +
<FONT Color=gray>' ''void *memcpy (void *__restrict __dest, const void *__restrict __src, size_t __n)''
 +
' ''Copy N bytes of SRC to DEST.''</font>
 +
Private Extern memcpy(__dest As Pointer, __src As Pointer, __n As Long) As Pointer
 +
 +
 +
Public Sub Main()
 +
 
 +
  Dim p, n As Pointer
 +
 
 +
  n = Alloc("X")
 +
  p = Alloc("abcdefg")
 +
 
 +
<FONT Color=gray>' ''Impostando il valore "1" al 3° argomento, non si imporrà il valore zero (&h00) dopo la posizione del carattere che sarà sostituito.''
 +
' ''Impostando il valore "2", invece, si imporrà il valore zero dopo la posizione del carattere che sarà sostituito, determinando coseguentemente l'arresto della stampa della stringa al carattere immediatamente precedente allo zero, ossia al carattere usato per la sostituzione.''</font>
 +
  memcpy(p + 3, n, CLong(1))
 +
 
 +
  Print String@(p)
 +
 
 +
  Free(p)
 +
  Free(n)
 +
 
 +
End
  
  

Versione attuale delle 14:12, 13 giu 2024

La funzione della libreria di C

void *memcpy(void *__restrict __dest, const void *__restrict __src, size_t __n)

copia n caratteri da un'area di memoria __src ad un'altra area di memoria __dest, entrambe puntate da due variabili di tipo Puntatore.

Va ricordato che per la variabile di tipo Puntatore del primo parametro (ossia: void *__restrict __dest) deve essere sempre allocata un'area di memoria di quantità adeguata.


Volendola utilizzare in Gambas, bisognerà dichiararla con Extern, nonché bisognerà dichiarare la libreria di C: libc.so.6, nella quale la funzione è contenuta:

Private Extern memcpy(__dest As Pointer, __src As Pointer, __n As Long) In "libc:6"


Semplice esempio di uso in Gambas con un valore numerico di tipo Intero

Library "libc:6"

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


Public Sub Main()

 Dim p1, p2 As Pointer
 Dim num As Integer
  
 num = 999

 p1 = VarPtr(num)
 p2 = Alloc(SizeOf(gb.Integer), 1)
  
 memcpy(p2, p1, SizeOf(gb.Integer))
  
 Print Int@(p2)

 Free(p2)

End


Semplice esempio di uso in Gambas con un valore di tipo Stringa

In questo caso il secondo parametro della funzione esterna memcpy( ) sarà di tipo Stringa.

Library "libc:6"

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


Public Sub Main()

 Dim dest As Pointer
 Dim src As String = "Questa è una prova con la funzione 'memcpy()'."
 Dim i As Integer
 
 i = Len(src)
  
' Allochiamo un'area di memoria adeguata per contenere tutti i valori costituenti i caratteri della stringa:
 dest = Alloc(SizeOf(gb.Byte), i)
   
' Il valore numerico del 3° argomento sarà aumentato di un'unità, affinché con la funzione nativa di dereferenziazione non si vada oltre i valori corrispondenti ai caratteri della stringa copiata.
 memcpy(dest, src, CLong(i + 1))
   
 Print "Dopo memcpy, " & Quote("dest") & ":\n"; String@(dest)
  
' Liberiamo l'area di memoria precedentemente allocata:
 Free(dest)
' Ci assicuriamo comunque che il Puntatore non punti ad alcuna cella importante di memoria:
 dest = 0
  
End


Copia di due stringhe

Di seguito un esempio per copiare in modo contiguo due stringhe all'interno di un'area di memoria riservata:

Library "libc:6"

' void *memcpy (void *__restrict __dest, const void *__restrict __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 a, b As String
 Dim dest As Pointer
 Dim i As Integer
 
 a = "aaaa"
 b = "bbbb"
  
 i = Len(a)
  
' Allochiamo un'area di memoria adeguata per contenere tutti i valori costituenti i caratteri della stringa:
 dest = Alloc(SizeOf(gb.Byte), i)
   
' Copiamo nell'area di memoria l'intero numero di dati contenuti dalla variabile stringa "a".
' Il valore numerico del 3° argomento sarà aumentato di un'unità, affinché con la funzione nativa di dereferenziazione non si vada oltre i valori corrispondenti ai caratteri della stringa copiata.
 memcpy(dest, a, CLong(i + 1))
   
' Poiché dobbiamo memorizzare successivamente anche i dati presenti nella variabile stringa "b", è necessario spostarci all'interno dell'area di memoria allocata di un numero di byte pari alla dimensione della stringa contenuta dalla variabile "a":
 dest += i
   
 i = Len(b)
   
' Copiamo nell'area di memoria, dopo i dati già copiati dalla variabile stringa "a", l'intero numero di dati contenuti dalla variabile stringa "b":
 memcpy(dest, b, CLong(i + 1))
   
' Poiché il puntatore interno dell'area di memoria riservata è spostato in avanti rispetto al primo byte dell'area medesima, è necessario riportarlo dunque all'inizio:
 dest -= i
   
' Dereferenziamo il Puntatore all'area di memoria allocata per vederne il contenuto in console:
 Print String@(dest)
   
' Liberiamo l'area di memoria precedentemente allocata:
 Free(dest)
' Ci assicuriamo comunque che il Puntatore non punti ad alcuna cella importante di memoria:
 dest = 0
  
End


In quest'altro esempio, per effettuare la copia di due stringhe, si utilizzerà un vettore di tipo Byte[ ]:

Library "libc:6"

' void *memcpy (void *__restrict __dest, const void *__restrict __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 a, b As String
 Dim dest As Byte[]
 Dim ia, ib As Integer
 
 a = "aaaa"
 b = "bbbb"
   
' Attribuiamo un sufficiente numero di elementi al vettore, ossia allochiamo una sufficiente area di memoria per il vettore medesimo:
 dest = New Byte[16]
   
 ia = Len(a)
   
' Copiamo nell'area di memoria l'intero numero di dati contenuti dalla variabile stringa "a":
 memcpy(dest.Data, a, CLong(ia + 1))
  
 ib = Len(b)
   
' Copiamo nell'area di memoria del vettore, destinata a memorizzare i propri dati, l'intero numero di dati contenuti dalla variabile stringa "b".
' L'area di memoria di memorizzazione dei dati del vettore è individuata dal suo indirizzo ritornato dalla proprietà ".Data" del vettore medesimo.
' Ci spostiamo di 4 byte avanti nell'area di memoria del vettore, al fine di non sovrascrivere i dati già copiati precedentemente della stringa "a":
 memcpy(dest.Data + ia, b, CLong(ib + 1))
  
' Mostriamo in console i dati "utili" (ossia in questo caso quelli rappresentanti la copia delle due stringhe originarie) contenuti dal vettore:
 Print dest.ToString(0, ia + ib)
  
' ...o magari leggendo con la funzione di dereferenziazione di Gambas direttamente nell'area di memoria dei dati memorizzati dal vettore:
 Print String@(dest.Data)
  
End


Sostituire un carattere all'interno di una stringa

In quest'altro caso sostituiremo un carattere all'interno di una stringa:

Library "libc:6"

' void *memcpy (void *__restrict __dest, const void *__restrict __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, n As Pointer
  
 n = Alloc("X")
 p = Alloc("abcdefg")
  
' Impostando il valore "1" al 3° argomento, non si imporrà il valore zero (&h00) dopo la posizione del carattere che sarà sostituito.
' Impostando il valore "2", invece, si imporrà il valore zero dopo la posizione del carattere che sarà sostituito, determinando coseguentemente l'arresto della stampa della stringa al carattere immediatamente precedente allo zero, ossia al carattere usato per la sostituzione.
 memcpy(p + 3, n, CLong(1))
  
 Print String@(p)
  
 Free(p)
 Free(n)
 
End


Riferimenti