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.
 
(2 versioni intermedie di uno stesso utente non sono mostrate)
Riga 1: Riga 1:
Spesso le Strtture esterne di librerie, scritte in C, tra i loro membri contengono anche ''Puntatori'' ad altre Strutture.
+
#REDIRECT [[Utilizzare_come_Struttura_in_Gambas_una_Struttura_esterna_dichiarata,_come_proprio_membro_di_tipo_Puntatore,_da_una_Struttura_principale_esterna]]
 
 
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.
 
<BR>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. <B><SUP>&#091;[[#Note|Nota 1]]&#093;</sup></b>
 
<BR>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
 
 
 
 
 
====Esempi pratici====
 
'''1''') Mostriamo un primo semplice codice esemplificativo, in cui si utilizza una libreria esterna, scritta in C, nella quale si ha una ''Struttura'' principale, che contiene tra i suoi membri un ''Puntatore'' ad una ''Struttura'' secondaria. Ai membri di entrambe le ''Strutture'' saranno assegnati dei valori, che saranno poi letti dal codice scritto in linguaggio Gambas.
 
Public Struct Secondaria
 
  si As Short
 
  i As Integer
 
  li As Long
 
End Struct
 
 
Public Struct PRINCIPALE
 
  c As Byte
 
  si As Short
 
  sec As Pointer
 
End Struct
 
 
 
Private Extern funzione(pp As PRINCIPALE) In "/tmp/libext"
 
 
'''Public''' Sub Main()
 
 
 
  Dim pr As New PRINCIPALE
 
  Dim seco As Secondaria
 
 
 
<FONT Color=gray>' ''Invoca la sotto-procedura per creare la libreria esterna contenente la funzione che sarà usata appresso:''</font>
 
  Creaso()
 
 
 
<FONT Color=gray>' ''Invoca la funzione contenuta nella libreria esterna "libext.so":''</font>
 
  funzione(pr)
 
 
 
<FONT Color=gray>' ''Assegna alla variabile di tipo della Struttura "Secondaria" il membro di tipo Puntatore della Struttura "PRINCIPALE", affinché si possano più agevolmente leggere (senza uso della risorsa ''Memory-Stream'') i valori assegnati alla Struttura "Secondaria" dalla funzione esterna:''</font>
 
  <B><FONT Color=#B22222>seco = pr.sec</font></b>
 
 
 
<FONT Color=gray>' ''Mostra dalla struttura "Secondaria", ricreata in Gambas, i valori assegnati alla corrispondente Struttura dalla funzione esterna:''</font>
 
  With seco
 
    Print .si
 
    Print .i
 
    Print .li
 
  End With
 
 
 
'''End'''
 
 
 
'''Private''' Procedure Creaso()
 
 
 
  File.Save("/tmp/libext.c", "#include <stdio.h>\n#include <stdlib.h>\n\n" &
 
            "struct Secondaria {\n" &
 
            "  unsigned short int si;\n" &
 
            "  unsigned int i;\n" &
 
            "  unsigned long int li;\n};\n\n" &
 
            "struct PRINCIPALE {\n" &
 
            "  unsigned char c;\n" &
 
            "  unsigned short int si;\n" &
 
            "  struct Secondaria *sec;  /* Membro di tipo \"Puntatore\" alla Struttura secondaria */\n};\n\n" &
 
            "void funzione (struct PRINCIPALE *pp) {" &
 
            "  pp->sec = malloc(sizeof(struct Secondaria));\n" &
 
            "  pp->c = 32;\n" &
 
            "  pp->si = 3200;\n" &
 
            "  pp->sec->si = 32000;\n" &
 
            "  pp->sec->i =  3200000;\n" &
 
            "  pp->sec->li =  32000000;\n\n}")
 
 
 
  Shell "gcc -o /tmp/libext.so /tmp/libext.c -shared" Wait
 
 
 
'''End'''
 
 
 
 
 
'''2''') Proponiamo l'analisi del seguente codice, con il quale è possibile conoscere i valori RGBA dei pixel di una immagine.
 
<BR>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''".
 
<BR>Si procederà come segue:
 
<BR>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.
 
<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>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"
 
 
 
Public Struct SDL_Rect
 
  x As Integer
 
  y As Integer
 
  w As Integer
 
  h As Integer
 
End Struct
 
 
<FONT Color=gray>' ''La Struttura principale viene dichiarata normalmente conformemente ai tipi dei suoi membri dichiarati nel API della libreria esterna''</font>
 
Public Struct SDL_Surface
 
  flags As Integer
 
  <FONT Color=#B22222>format As Pointer</font>  <FONT Color=gray>' ''Il membro che punta alla Struttura secondaria "SDL_PixelFormat"''</font>
 
  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
 
 
<FONT Color=gray>' ''La Struttura secondaria viene dichiarata normalmente conformemente ai tipi dei suoi membri dichiarati nel API della libreria esterna''</font>
 
Public Struct SDL_PixelFormat
 
  format As Integer
 
  palette As Pointer
 
  BitsPerPixel As Byte
 
  BytesPerPixel As Byte  <FONT Color=gray>' ''Il membro dal quale leggere il valore''</font>
 
  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
 
 
<FONT Color=gray>' ''int SDL_Init(Uint32 flags)''
 
' ''Initialize the SDL library.''</font>
 
Private Extern SDL_Init(flags As Integer) As Integer
 
 
<FONT Color=gray>' ''void SDL_Quit(void)''
 
' ''Clean up all initialized subsystems.''</font>
 
Private Extern SDL_Quit()
 
 
 
Library "libSDL2_image-2.0:0.2.3"
 
 
<FONT Color=gray>' ''SDL_Surface * IMG_Load(const char *file)''
 
' ''Load an image from an SDL data source.''</font>
 
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 = "<FONT Color=gray>''/percorso/del/file/immagine''</font>"
 
 
 
  SDL_Init(SDL_INIT_VIDEO)
 
 
 
  imago = IMG_Load(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é poi possa essere usato comodamente il membro ".BytesPerPixel" della predetta Struttura "SDL_PixelFormat":''</font>
 
  <B><FONT Color=#B22222>pxfmt = imago.format</font></b>
 
 
 
 
 
<FONT Color=gray>' ''Legge il valore del membro cercato:''</font>
 
  Print pxfmt.BytesPerPixel
 
 
 
<FONT Color=gray>' ''Chiude la libreria "SDL2":''</font>
 
  SDL_Quit()
 
 
 
'''End'''
 
 
 
 
 
 
 
=Note=
 
[1] Vedi anche la seguente pagina: [[Dereferenziare_senza_Memory-Stream_un_pointer_ad_una_Struttura,_passato_da_una_funzione_esterna|Dereferenziare senza Memory-Stream un pointer ad una Struttura, passato da una funzione esterna]]
 

Versione attuale delle 17:22, 17 ago 2020