Differenze tra le versioni di "Ottenere il puntatore di una variabile di tipo Struttura"

Da Gambas-it.org - Wikipedia.
 
(25 versioni intermedie di uno stesso utente non sono mostrate)
Riga 1: Riga 1:
 
E' possibile ottenere il ''Puntatore'' di una variabile di tipo ''Struttura'' (ossia una variabile di tipo ''Puntatore'' che ''punta'' all'indirizzo di memoria di una variabile di tipo ''Struttura'') mediante almeno due modalità:
 
E' possibile ottenere il ''Puntatore'' di una variabile di tipo ''Struttura'' (ossia una variabile di tipo ''Puntatore'' che ''punta'' all'indirizzo di memoria di una variabile di tipo ''Struttura'') mediante almeno due modalità:
* con la funzione ''VarPtr( )'';
+
* con la funzione "VarPtr()";
* con il metodo ''Object.Address()''.
+
* con il Metodo "Object.Address()".
  
 
+
=Ottenere il puntatore di una variabile di tipo Struttura mediante la funzione "VarPtr()"=
==Ottenere il puntatore di una variabile di tipo Struttura mediante la funzione ''VarPtr( )''==
+
La funzione "VarPtr()" ritorna un ''Puntatore'' che punta alla variabile contenuta in memoria; pertanto si utilizzerà con la variabile di tipo ''Struttura'' con la seguente sintassi:
La funzione ''VarPtr( )'' ritorna un ''Puntatore'' che punta alla variabile contenuta in memoria; pertanto si utilizzerà con la variabile di tipo ''Struttura'' con la seguente sintassi:
 
 
  <FONT color=B22222><B>VarPtr</b></font>(Variabile_Struttura) As Pointer
 
  <FONT color=B22222><B>VarPtr</b></font>(Variabile_Struttura) As Pointer
  
V'è da sottolineare che la variabile di tipo ''Struttura'' andrà assolutamente dichiarata all'esterno delle routine, come ''globale'', e preceduta dalla parola chiave ''Struct'':
+
V'è da sottolineare che la variabile di tipo ''Struttura'' andrà assolutamente dichiarata all'esterno delle routine, come ''globale'', e preceduta dalla parola-chiave '''Struct''':
 
  Private variabile_struttura As <FONT color=B22222>Struct</font> STRUTTURA
 
  Private variabile_struttura As <FONT color=B22222>Struct</font> STRUTTURA
  
Da sottolineare che in questo caso i dati sono presenti all'interno dell'area di memoria della Struttura a cominciare dal 1° byte (indice 0).
+
Da sottolineare che in questo caso i dati sono presenti all'interno dell'area di memoria, puntata dal ''Puntatore'', a cominciare dal 1° byte (indice 0). Pertanto possiamo dire che il ''Puntatore'' alla variabile di tipo ''Struttura'', ritornato dalla funzione "VarPtr()", punta all'indirizzo di memoria dei dati associati alla ''Struttura'', ossia all'indirizzo di memoria del <U>primo</u> membro della ''Struttura''. <SUP>&#091;[[#Note|nota 1]]&#093;</sup>
  
 
Esempio:
 
Esempio:
  '''Public''' Struct abcde
+
  Public Struct ABCDE
 
   a As Byte
 
   a As Byte
 
   b As Short
 
   b As Short
Riga 20: Riga 19:
 
   d As Long
 
   d As Long
 
   e As String
 
   e As String
  '''End''' Struct
+
  End Struct
 
'''Private''' vrSt As <FONT color=B22222>Struct</font> Abcde
 
 
   
 
   
 +
Private vrSt As <FONT color=B22222><B>Struct</b></font> ABCDE
 
   
 
   
'''Public''' Sub Main()
 
 
   
 
   
  Dim p1, p2 As Pointer
+
Public Sub Main()
  Dim b As Byte
 
  Dim sr As Short
 
  Dim i As Integer
 
  Dim l As Long
 
  Dim t As Stream
 
 
   
 
   
 +
  Dim p1, p2 As Pointer
 
   
 
   
 
   With vrSt
 
   With vrSt
Riga 44: Riga 37:
 
   
 
   
 
   
 
   
  <FONT color=gray>' ''Creiamo il "Puntatore" alla variabile di tipo "Struttura":''</font>
+
  <FONT color=gray>' ''Ottiene il "Puntatore" alla variabile di tipo "Struttura":''</font>
   p1 = <FONT color=B22222>VarPtr(</font>vrSt<FONT color=B22222>)</font>
+
   p1 = <FONT color=B22222><B>VarPtr</b></font>(vrSt)
 +
 +
<FONT color=gray>' ''Dereferenzia il "Puntatore" mediante l'apposita funzione nativa di Gambas per leggere un Byte, spostandosi al numero d'indice "24" dell'area allocata appartenente alla Struttura:''</font>
 +
  Print Byte@(p1)
 +
 +
<FONT color=gray>' ''Per leggere il valore del membro di tipo "Short", usa l'apposita funzione nativa di Gambas, spostandosi al numero d'indice "2" dell'area allocata, e non "1", per rispettare la regola dell'Allineamento dei dati:</font>
 +
  Print Short@(p1 + SizeOf(gb.Short))
 
   
 
   
  <FONT color=gray>' ' ' ' ' '</font>
+
  <FONT color=gray>' ''Per leggere il valore del membro di tipo "Integer", usa l'apposita funzione nativa di Gambas, spostandosi al numero d'indice "4" dell'area allocata:</font>
 +
  Print Integer@(p1 + SizeOf(gb.Integer))
 
   
 
   
  <FONT color=gray>' ''Ora ri-otteniamo i valori presenti nella "Struttura"''
+
  <FONT color=gray>' ''Per leggere il valore del membro di tipo "Long", usa l'apposita funzione nativa di Gambas, spostandosi al numero d'indice "8" dell'area allocata:</font>
  ' ''dereferenziando con i "Memory-Stream" il "Puntatore" prima creato:''</font>
+
  Print Long@(p1 + SizeOf(gb.Long))
   t = Memory p1 For Read
+
 
 +
  <FONT color=gray>' ''Se un membro della "Struttura" è di tipo "Stringa", allora la corrispondente area di memoria contiene un indirizzo di memoria di una "Stringa". In tal caso detto indirizzo di memoria dovrà essere innanzitutto opportunamente dereferenziato con l'apposita funzione nativa di Gambas, adatta per dereferenziare i "Puntatori":''</font>
 +
  p2 = Pointer@(p1 + 16)
 +
<FONT color=gray>' ''Quindi dereferenzia il "Puntatore" ottenuto, per ottenere la stringa:</font>
 +
   Print String@(p2)
 
   
 
   
  Read #t, b
+
End
   Print b
+
Si può usare anche un ciclo per l'intera dimensione della "Struttura", mostrando così tutta area di memoria della "Struttura":
 +
  Dim i As Integer
 +
  ......
 +
  ......
 +
  For i = 0 To Object.SizeOf(vrSt) - 1
 +
    If i = Object.SizeOf(vrSt) - 8 Then
 +
      Print String@(p2)
 +
      Break
 +
    Endif
 +
    Print i, Hex(Byte@(p1 + i), 2)
 +
  Next
 +
 
 +
 
 +
=Ottenere il puntatore di una variabile di tipo Struttura mediante il Metodo "Object.Address()"=
 +
Il Metodo ".Address()" della Classe '' Object'' ritorna l'indirizzo di memoria dell'Oggetto ''Struttura'', e si utilizzerà con la variabile di tipo ''Struttura'' con la seguente sintassi:
 +
<FONT color=B22222><B>Object.Address</b></font>(Variabile_Struttura) As Pointer
 +
In questo caso è preferibile optare per la dichiarazione della variabile di tipo ''Struttura'' con la parola '''New''':
 +
Dim variabile_struttura As <FONT color=B22222>New</font> STRUTTURA
 +
Da sottolineare che in questo caso i dati sono presenti all'interno dell'area di memoria, puntata dal ''Puntatore'', a cominciare dal 25° byte (indice 24).
 +
 
 +
Mostriamo un esempio riprendendo come base quello precedente:
 +
Public Struct ABCDE
 +
  a As Byte
 +
   b As Short
 +
  c As Integer
 +
  d As Long
 +
  e As String
 +
End Struct
 +
 
 
   
 
   
  Seek #t, 2
+
Public Sub Main()
  Read #t, sr
 
  Print sr
 
 
   
 
   
   Read #t, i
+
   Dim vrSt As <FONT color=B22222>'''New'''</font> ABCDE
   Print i
+
   Dim p1, p2 As Pointer
 
   
 
   
   Read #t, l
+
   With vrSt
   Print l
+
    .a = 9
 +
    .b = 999
 +
    .c = 999999
 +
    .d = 999999999
 +
    .e = "testo"
 +
  End With
 +
 
 +
<FONT color=gray>' ''Ottiene il "Puntatore" all'Oggetto "Struttura" dalla sua variabile:''</font>
 +
   p1 = <FONT color=B22222><B>Object.Address</b></font>(vrSt)
 
   
 
   
  <FONT color=gray>' ''Se i byte dell'area di memoria dello "Stream" contengono un indirizzo di memoria di una "Stringa",''
+
  <FONT color=gray>' ''Dereferenzia il "Puntatore" mediante l'apposita funzione nativa di Gambas per leggere un Byte, spostandosi al numero d'indice "24" dell'area allocata appartenente alla Struttura:''</font>
' ''allora leggiamo insieme questi byte e li assegnamo ad una variabile di tipo "Puntatore"; quindi poi dereferenziamo per ottenere la stringa:''</font>
+
   Print Byte@(p1 + <FONT color=B22222><B>24</b></font>)
  Seek #t, 16
 
  Read #t, p2
 
   Print String@(p2)
 
 
   
 
   
  <FONT color=gray>' ''oppure anche con un ciclo per l'intera dimensione della "Struttura", mostrando così tutta area di memoria della "Struttura":''
+
  <FONT color=gray>' ''Per leggere il valore del membro di tipo "Short", usa l'apposita funzione nativa di Gambas, spostandosi al numero d'indice "26" dell'area allocata, e non "25", per rispettare la regola dell'Allineamento dei dati:</font>
   For j = 0 To Object.SizeOf(vrSt) - 1
+
   Print Short@(p1 + <FONT color=B22222><B>24</b></font> + SizeOf(gb.Short))
    If j = Object.SizeOf(vrSt) - 8 Then
 
      Read #t, p2
 
      Print String@(p2)
 
      Quit
 
    Endif
 
    Read #t, b
 
    Print j, b, Hex(b, 16)
 
  Next</font>
 
 
   
 
   
 +
<FONT color=gray>' ''Per leggere il valore del membro di tipo "Integer", usa l'apposita funzione nativa di Gambas, spostandosi al numero d'indice "28" dell'area allocata:</font>
 +
  Print Integer@(p1 + <FONT color=B22222><B>24</b></font> + SizeOf(gb.Integer))
 
   
 
   
   t.Close
+
<FONT color=gray>' ''Per leggere il valore del membro di tipo "Long", usa l'apposita funzione nativa di Gambas, spostandosi al numero d'indice "32" dell'area allocata:</font>
 +
   Print Long@(p1 + <FONT color=B22222><B>24</b></font> + SizeOf(gb.Long))
 +
 
 +
<FONT color=gray>' ''Se un membro della "Struttura" è di tipo "Stringa", allora la corrispondente area di memoria contiene un indirizzo di memoria di una "Stringa". In tal caso detto indirizzo di memoria dovrà essere innanzitutto opportunamente dereferenziato con l'apposita funzione nativa di Gambas, adatta per dereferenziare i "Puntatori":''</font>
 +
  p2 = Pointer@(p1 + <FONT color=B22222><B>24</b></font> + 16)
 +
<FONT color=gray>' ''Quindi dereferenzia il "Puntatore" ottenuto, per ottenere la stringa:</font>
 +
  Print String@(p2)
 
   
 
   
  '''End'''
+
  End
 +
Si può usare anche un ciclo per l'intera dimensione della "Struttura", mostrando così tutta area di memoria della "Struttura":
 +
  Dim i As Integer
 +
  ......
 +
  ......
 +
  For i = 0 To Object.SizeOf(vrSt) - 1
 +
    If i = Object.SizeOf(vrSt) - 8 Then
 +
      Print String@(p2)
 +
      Break
 +
    Endif
 +
    Print i, Hex(Byte@(p1 + 24 + i), 2)
 +
  Next
 +
Per vedere un altro esempio del suo uso si rinvia a questa pagina della Wiki:
 +
[[Leggere e scrivere direttamente nell'area di memoria di una Struttura accedendovi con la classe Object]].
  
  
  
==Ottenere il puntatore di una variabile di tipo Struttura mediante il metodo ''Object.Address()''==
+
=Note=
In particolare tale metodo ritorna l'indirizo di memoria dell'oggetto posto come parametro del metodo stesso, e si utilizzerà con la variabile di tipo ''Struttura'' con la seguente sintassi:
+
[1] Vedere anche la seguente pagina: [[Ottenere il puntatore direttamente ai dati associati a una Struttura]]
<FONT color=B22222><B>Object.Address</b></font>(Variabile_Struttura) As Pointer
 
In questo caso è preferibile optare per la dichiarazione della variabile di tipo ''Struttura'' con la parola ''New'':
 
Dim variabile_struttura As <FONT color=B22222>New</font> STRUTTURA
 
Da sottolineare che in questo caso i dati sono presenti all'interno dell'area di memoria della ''Struttura'' a cominciare dal 25° byte (indice 24).
 
 
 
Per vedere un esempio del suo uso si rinvia a [[Leggere_e_scrivere_in_una_Struttura_con_i_Memory_Stream|questa pagina della WIKI]].
 

Versione attuale delle 19:04, 7 giu 2024

E' possibile ottenere il Puntatore di una variabile di tipo Struttura (ossia una variabile di tipo Puntatore che punta all'indirizzo di memoria di una variabile di tipo Struttura) mediante almeno due modalità:

  • con la funzione "VarPtr()";
  • con il Metodo "Object.Address()".

Ottenere il puntatore di una variabile di tipo Struttura mediante la funzione "VarPtr()"

La funzione "VarPtr()" ritorna un Puntatore che punta alla variabile contenuta in memoria; pertanto si utilizzerà con la variabile di tipo Struttura con la seguente sintassi:

VarPtr(Variabile_Struttura) As Pointer

V'è da sottolineare che la variabile di tipo Struttura andrà assolutamente dichiarata all'esterno delle routine, come globale, e preceduta dalla parola-chiave Struct:

Private variabile_struttura As Struct STRUTTURA

Da sottolineare che in questo caso i dati sono presenti all'interno dell'area di memoria, puntata dal Puntatore, a cominciare dal 1° byte (indice 0). Pertanto possiamo dire che il Puntatore alla variabile di tipo Struttura, ritornato dalla funzione "VarPtr()", punta all'indirizzo di memoria dei dati associati alla Struttura, ossia all'indirizzo di memoria del primo membro della Struttura. [nota 1]

Esempio:

Public Struct ABCDE
  a As Byte
  b As Short
  c As Integer
  d As Long
  e As String
End Struct

Private vrSt As Struct ABCDE


Public Sub Main()

  Dim p1, p2 As Pointer

  With vrSt
    .a = 9
    .b = 999
    .c = 999999
    .d = 999999999
    .e = "testo"
  End With


' Ottiene il "Puntatore" alla variabile di tipo "Struttura":
  p1 = VarPtr(vrSt)

' Dereferenzia il "Puntatore" mediante l'apposita funzione nativa di Gambas per leggere un Byte, spostandosi al numero d'indice "24" dell'area allocata appartenente alla Struttura:
  Print Byte@(p1)

' Per leggere il valore del membro di tipo "Short", usa l'apposita funzione nativa di Gambas, spostandosi al numero d'indice "2" dell'area allocata, e non "1", per rispettare la regola dell'Allineamento dei dati:
  Print Short@(p1 + SizeOf(gb.Short))

' Per leggere il valore del membro di tipo "Integer", usa l'apposita funzione nativa di Gambas, spostandosi al numero d'indice "4" dell'area allocata:
  Print Integer@(p1 + SizeOf(gb.Integer))

' Per leggere il valore del membro di tipo "Long", usa l'apposita funzione nativa di Gambas, spostandosi al numero d'indice "8" dell'area allocata:
  Print Long@(p1 + SizeOf(gb.Long))
 
' Se un membro della "Struttura" è di tipo "Stringa", allora la corrispondente area di memoria contiene un indirizzo di memoria di una "Stringa". In tal caso detto indirizzo di memoria dovrà essere innanzitutto opportunamente dereferenziato con l'apposita funzione nativa di Gambas, adatta per dereferenziare i "Puntatori":
  p2 = Pointer@(p1 + 16)
' Quindi dereferenzia il "Puntatore" ottenuto, per ottenere la stringa:
  Print String@(p2)

End

Si può usare anche un ciclo per l'intera dimensione della "Struttura", mostrando così tutta area di memoria della "Struttura":

 Dim i As Integer
 ......
 ......
 For i = 0 To Object.SizeOf(vrSt) - 1
   If i = Object.SizeOf(vrSt) - 8 Then
     Print String@(p2)
     Break
   Endif
   Print i, Hex(Byte@(p1 + i), 2)
 Next


Ottenere il puntatore di una variabile di tipo Struttura mediante il Metodo "Object.Address()"

Il Metodo ".Address()" della Classe Object ritorna l'indirizzo di memoria dell'Oggetto Struttura, e si utilizzerà con la variabile di tipo Struttura con la seguente sintassi:

Object.Address(Variabile_Struttura) As Pointer

In questo caso è preferibile optare per la dichiarazione della variabile di tipo Struttura con la parola New:

Dim variabile_struttura As New STRUTTURA

Da sottolineare che in questo caso i dati sono presenti all'interno dell'area di memoria, puntata dal Puntatore, a cominciare dal 25° byte (indice 24).

Mostriamo un esempio riprendendo come base quello precedente:

Public Struct ABCDE
  a As Byte
  b As Short
  c As Integer
  d As Long
  e As String
End Struct
 

Public Sub Main()

  Dim vrSt As New ABCDE
  Dim p1, p2 As Pointer

  With vrSt
    .a = 9
    .b = 999
    .c = 999999
    .d = 999999999
    .e = "testo"
  End With
 
' Ottiene il "Puntatore" all'Oggetto "Struttura" dalla sua variabile:
  p1 = Object.Address(vrSt)

' Dereferenzia il "Puntatore" mediante l'apposita funzione nativa di Gambas per leggere un Byte, spostandosi al numero d'indice "24" dell'area allocata appartenente alla Struttura:
  Print Byte@(p1 + 24)

' Per leggere il valore del membro di tipo "Short", usa l'apposita funzione nativa di Gambas, spostandosi al numero d'indice "26" dell'area allocata, e non "25", per rispettare la regola dell'Allineamento dei dati:
  Print Short@(p1 + 24 + SizeOf(gb.Short))

' Per leggere il valore del membro di tipo "Integer", usa l'apposita funzione nativa di Gambas, spostandosi al numero d'indice "28" dell'area allocata:
  Print Integer@(p1 + 24 + SizeOf(gb.Integer))

' Per leggere il valore del membro di tipo "Long", usa l'apposita funzione nativa di Gambas, spostandosi al numero d'indice "32" dell'area allocata:
  Print Long@(p1 + 24 + SizeOf(gb.Long))
 
' Se un membro della "Struttura" è di tipo "Stringa", allora la corrispondente area di memoria contiene un indirizzo di memoria di una "Stringa". In tal caso detto indirizzo di memoria dovrà essere innanzitutto opportunamente dereferenziato con l'apposita funzione nativa di Gambas, adatta per dereferenziare i "Puntatori":
  p2 = Pointer@(p1 + 24 + 16)
' Quindi dereferenzia il "Puntatore" ottenuto, per ottenere la stringa:
  Print String@(p2)

End

Si può usare anche un ciclo per l'intera dimensione della "Struttura", mostrando così tutta area di memoria della "Struttura":

 Dim i As Integer
 ......
 ......
 For i = 0 To Object.SizeOf(vrSt) - 1
   If i = Object.SizeOf(vrSt) - 8 Then
     Print String@(p2)
     Break
   Endif
   Print i, Hex(Byte@(p1 + 24 + i), 2)
 Next

Per vedere un altro esempio del suo uso si rinvia a questa pagina della Wiki: Leggere e scrivere direttamente nell'area di memoria di una Struttura accedendovi con la classe Object.


Note

[1] Vedere anche la seguente pagina: Ottenere il puntatore direttamente ai dati associati a una Struttura