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"
Riga 84: | Riga 84: | ||
<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. | + | Library "libSDL2-2.0:0.3000.3" |
Public Struct SDL_Rect | Public Struct SDL_Rect | ||
Riga 142: | Riga 142: | ||
− | Library "libSDL2_image-2.0:0.2 | + | Library "libSDL2_image-2.0:0.800.2" |
<FONT Color=gray>' ''SDL_Surface * IMG_Load(const char *file)'' | <FONT Color=gray>' ''SDL_Surface * IMG_Load(const char *file)'' | ||
Riga 157: | Riga 157: | ||
Dim i As Integer | Dim i As Integer | ||
− | immagine = "<FONT Color= | + | immagine = "<FONT Color=darkgreen>''/percorso/del/file/immagine''</font>" |
SDL_Init(SDL_INIT_VIDEO) | SDL_Init(SDL_INIT_VIDEO) | ||
Riga 163: | Riga 163: | ||
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é poi 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> | ||
<B><FONT Color=#B22222>pxfmt = imago.format</font></b> | <B><FONT Color=#B22222>pxfmt = imago.format</font></b> | ||
− | + | ||
− | + | <FONT Color=gray>' ''Legge il valore di ciascun membro cercato:''</font> | |
− | <FONT Color=gray>' ''Legge il valore | + | With pxfmt |
− | Print | + | Print .BitsPerPixel |
− | + | Print .BytesPerPixel | |
+ | End With | ||
+ | |||
<FONT Color=gray>' ''Chiude la libreria "SDL2":''</font> | <FONT Color=gray>' ''Chiude la libreria "SDL2":''</font> | ||
SDL_Quit() | SDL_Quit() |
Versione delle 15:50, 7 giu 2024
Spesso le Strtture esterne di librerie, scritte in C, contengono tra i loro membri 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
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 ' Il seguente membro corrisponde al membro di tipo "Puntatore" della "Struttura" Principale in C, che punta alla Struttura secondaria: sec As Pointer End Struct ' void funzione (struct PRINCIPALE *pp) ' Assegna dei valori alle due Strutture "PRINCIPALE" e "Secondaria". Private Extern funzione(pp As PRINCIPALE) In "/tmp/libext" Public Sub Main() Dim pr As New PRINCIPALE Dim seco As Secondaria ' Invoca la sotto-procedura per creare la libreria esterna contenente la funzione che sarà usata appresso: Creaso() ' Invoca la funzione contenuta nella libreria esterna "libext.so": funzione(pr) ' 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: seco = pr.sec ' Mostra dalla struttura "Secondaria", ricreata in Gambas, i valori assegnati alla corrispondente Struttura dalla funzione esterna: 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.
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.3000.3" 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.800.2" ' 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 di ciascun membro cercato: With pxfmt Print .BitsPerPixel Print .BytesPerPixel End With ' Chiude la libreria "SDL2": SDL_Quit() End
Note
[1] Vedi anche la seguente pagina: Dereferenziare senza Memory-Stream un Puntatore ad una Struttura, passato da una funzione esterna