Differenze tra le versioni di "Utilizzare come Struttura in Gambas una Struttura esterna, dichiarata come proprio membro di tipo Puntatore, da una Struttura principale esterna"

Da Gambas-it.org - Wikipedia.
Riga 15: Riga 15:
 
<BR>2) il membro della Struttura principale (in questo esempio è "''SDL_Surface.format''") di tipo ''Puntatore'', che punta alla Struttura secondaria (in questo esempio "''SDL_PixelFormat'") si dichiarerà come ''Puntatore''.
 
<BR>2) il membro della Struttura principale (in questo esempio è "''SDL_Surface.format''") di tipo ''Puntatore'', che punta alla Struttura secondaria (in questo esempio "''SDL_PixelFormat'") si dichiarerà come ''Puntatore''.
 
<BR>3) la predetta Struttura secondaria ("''SDL_PixelFormat'") sarà scritta e dichiarata in Gambas come una normale Struttura, avendo cura di rispettare la tipologia dei membri della corrispondente Struttura esterna in modo tale che esse siano omogenee.
 
<BR>3) la predetta Struttura secondaria ("''SDL_PixelFormat'") sarà scritta e dichiarata in Gambas come una normale Struttura, avendo cura di rispettare la tipologia dei membri della corrispondente Struttura esterna in modo tale che esse siano omogenee.
<BR>4) si assegnerà il membro "''SDL_Surface.format''" di tipo Puntatore della Struttura esterna principale alla Struttura secondaria ("''SDL_PixelFormat'"), assegnando così l'<I>indirizzo di memoria</i>, contenuto dalla variabile di tipo  ''Puntatore'', alla variabile di tipo ''Struttura''.
+
<BR>4) si assegnerà il membro "''SDL_Surface.format''" di tipo Puntatore della Struttura esterna principale alla Struttura secondaria ("''SDL_PixelFormat''"), assegnando così l'<I>indirizzo di memoria</i>, contenuto dalla variabile di tipo  ''Puntatore'', alla variabile di tipo ''Struttura''.
 
  Library "libSDL2-2.0:0.10.0"
 
  Library "libSDL2-2.0:0.10.0"
 
    
 
    
Riga 89: Riga 89:
 
   Dim i As Integer
 
   Dim i As Integer
 
    
 
    
  immagine = "<FONT Color=gray>''/percorso/del/file/immagine''</font>"
+
  immagine = "<FONT Color=gray>''/percorso/del/file/immagine''</font>"
 
    
 
    
  SDL_Init(SDL_INIT_VIDEO)
+
  SDL_Init(SDL_INIT_VIDEO)
 
    
 
    
  imago = IMG_Load(immagine)
+
  imago = IMG_Load(immagine)
  If IsNull(imago) Then Error.Raise("Impossibile caricare un'immagine !")
+
  If IsNull(imago) Then Error.Raise("Impossibile caricare un'immagine !")
 +
 
 
    
 
    
  <FONT Color=gray>' ''Assegna il membro ".format" di tipo Puntatore della Struttura "SDL_Surface" alla variabile di tipo della Struttura "SDL_PixelFormat", affinché possa essere usato comodamente il membro ".BytesPerPixel" della predetta Struttura "SDL_PixelFormat":''</font>
+
  <FONT Color=gray>' ''Assegna il membro ".format" di tipo Puntatore della Struttura "SDL_Surface" alla variabile di tipo della Struttura "SDL_PixelFormat", affinché poi possa essere usato comodamente il membro ".BytesPerPixel" della predetta Struttura "SDL_PixelFormat":''</font>
  <FONT Color=#B22222>pxfmt = imago.format</font>
+
  <B><FONT Color=#B22222>pxfmt = imago.format</font></b>
 +
 
 
    
 
    
 
  <FONT Color=gray>' ''Legge il valore del membro cercato:''</font>
 
  <FONT Color=gray>' ''Legge il valore del membro cercato:''</font>
  Print pxfmt.BytesPerPixel
+
  Print pxfmt.BytesPerPixel
     
 
 
    
 
    
 
  <FONT Color=gray>' ''Chiude la libreria "SDL2":''</font>
 
  <FONT Color=gray>' ''Chiude la libreria "SDL2":''</font>
  SDL_Quit()
+
  SDL_Quit()
 
    
 
    
 
  '''End'''
 
  '''End'''

Versione delle 09:24, 17 ago 2020

Spesso le Strtture esterne di librerie, scritte in C, tra i loro membri contengono anche Puntatori ad altre Strutture.

Essendo tali membri, dunque, dei Puntatori, qualora li si volesse dereferenziare in Gambas per leggere i dati, contenuti nei membri delle Strutture, da essi puntate, o per scrivervi, devono essere gestiti ovviamente con le consuete modalità previste per la lettura e la scrittura di dati nelle aree di memoria allocate e puntate dalle variabili di tipo Puntatore.

E', però, possibile gestire in Gambas tali Strutture secondarie, puntate da membri di tipo Puntatori di Strutture principali, tenendo conto che la variabile di tipo Struttura contiene l'indirizzo di memoria della Struttura medesima.
In particolare bisognerà dichiarare nel progetto Gambas una Struttura del tutto omogenea a quella esterna secondaria puntata, ed assegnare alla variabile della Struttura scritta in Gambas il membro di tipo Puntatore della Struttura esterna principale che punta alla Struttura secondaria esterna. [Nota 1]
Nel codice, dunque, ciò avviene assegnando il membro di tipo Puntatore della Struttura principale alla variabile del tipo della Struttura ricreata in Gambas:

variabile_struttura_ricreata = membro_di tipo_puntatore

Esempio pratico

Proponiamo l'analisi del seguente codice, con il quale è possibile conoscere i valori RGBA dei pixel di una immagine.
Scopo del codice è quello di leggere il valore contenuto nel membro "BytesPerPixel" della Struttura "SDL_PixelFormat", puntata dal membro "format" di tipo Puntatore della Struttura "SDL_Surface", dichiarata nel file header "/usr/include/SDL2/SDL_surface.h".
Si procederà come segue:
1) la Struttura principale (in questo esempio è "SDL_Surface") sarà scritta e dichiarata in Gambas come una normale Struttura, avendo cura di rispettare la tipologia dei membri della corrispondente Struttura esterna in modo tale che esse siano omogenee.
2) il membro della Struttura principale (in questo esempio è "SDL_Surface.format") di tipo Puntatore, che punta alla Struttura secondaria (in questo esempio "SDL_PixelFormat'") si dichiarerà come Puntatore.
3) la predetta Struttura secondaria ("SDL_PixelFormat'") sarà scritta e dichiarata in Gambas come una normale Struttura, avendo cura di rispettare la tipologia dei membri della corrispondente Struttura esterna in modo tale che esse siano omogenee.
4) si assegnerà il membro "SDL_Surface.format" di tipo Puntatore della Struttura esterna principale alla Struttura secondaria ("SDL_PixelFormat"), assegnando così l'indirizzo di memoria, contenuto dalla variabile di tipo Puntatore, alla variabile di tipo Struttura.

Library "libSDL2-2.0:0.10.0"
 
Public Struct SDL_Rect
  x As Integer
  y As Integer
  w As Integer
  h As Integer
End Struct

' La Struttura principale viene dichiarata normalmente conformemente ai tipi dei suoi membri dichiarati nel API della libreria esterna
Public Struct SDL_Surface
  flags As Integer
  format As Pointer   ' Il membro che punta alla Struttura secondaria "SDL_PixelFormat"
  w As Integer
  h As Integer
  pitch As Integer
  pixels As Pointer
  userdata As Pointer
  locked As Integer
  lock_data As Pointer
  clip_rect As Struct SDL_Rect
  map As Pointer
  refcount As Integer
End Struct

' La Struttura secondaria viene dichiarata normalmente conformemente ai tipi dei suoi membri dichiarati nel API della libreria esterna
Public Struct SDL_PixelFormat
  format As Integer
  palette As Pointer
  BitsPerPixel As Byte
  BytesPerPixel As Byte   ' Il membro dal quale leggere il valore
  Rmask As Integer
  Gmask As Integer
  BMask As Integer
  AMask As Integer
  Rloss As Byte
  Gloss As Byte
  Bloss As Byte
  Aloss As Byte
  Rshift As Byte
  Gshift As Byte
  Bshift As Byte
  Ashift As Byte
  refcount As Integer
  next_ As Pointer
End Struct

Private Const SDL_INIT_VIDEO As Integer = &20

' int SDL_Init(Uint32 flags)
' Initialize the SDL library.
Private Extern SDL_Init(flags As Integer) As Integer

' void SDL_Quit(void)
' Clean up all initialized subsystems.
Private Extern SDL_Quit()


Library "libSDL2_image-2.0:0.2.3"

' SDL_Surface * IMG_Load(const char *file)
' Load an image from an SDL data source.
Private Extern IMG_Load(_file As String) As SDL_Surface


Public Sub Main()
 
 Dim immagine As String
 Dim imago As SDL_Surface
 Dim pxfmt As SDL_PixelFormat
 Dim bpp As Byte
 Dim i As Integer
  
 immagine = "/percorso/del/file/immagine"
  
 SDL_Init(SDL_INIT_VIDEO)
  
 imago = IMG_Load(immagine)
 If IsNull(imago) Then Error.Raise("Impossibile caricare un'immagine !")
 
  
' Assegna il membro ".format" di tipo Puntatore della Struttura "SDL_Surface"  alla variabile di tipo della Struttura "SDL_PixelFormat", affinché poi possa essere usato comodamente il membro ".BytesPerPixel" della predetta Struttura "SDL_PixelFormat":
 pxfmt = imago.format
 
  
' Legge il valore del membro cercato:
 Print pxfmt.BytesPerPixel
  
' Chiude la libreria "SDL2":
 SDL_Quit()
  
End


Note

[1] Vedi anche la seguente pagina: Dereferenziare senza Memory-Stream un pointer ad una Struttura, passato da una funzione esterna