Differenze tra le versioni di "Gestire con sicurezza le Strutture esterne"
Riga 30: | Riga 30: | ||
==Leggere e scrivere nei membri delle ''Strutture''== | ==Leggere e scrivere nei membri delle ''Strutture''== | ||
− | Per leggere e scrivere nei membri che ci interessano di una ''Struttura'', si porrano nella nostra libreria ''ad hoc'' una serie di funzioni, alle quali come loro argomento si passerà una variabile di tipo ''Puntatore'', avendo avuto l'accortezza | + | Per leggere e scrivere nei membri che ci interessano di una ''Struttura'', si porrano nella nostra libreria ''ad hoc'' una serie di funzioni, alle quali come loro argomento si passerà una variabile di tipo ''Puntatore'', avendo avuto l'accortezza nel codice Gambas di dimensionare oppurtunamente ed adeguatamente (ossia riservare un'area di memoria <SPAN style= "text-decoration:underline">di dimensione identica</span> a quella della Struttura da gestire) tale ''Puntatore'' mediante la funzione ''Alloc()'' nella modalità vista nel precedente paragrafo "''Conoscere la dimensione di una Struttura da utilizzare''". |
<BR>Se, invece, vi è una funzione esterna della libreria esterna principale che inizializza (e quindi anche dimensionandola) nel codice Gambas la variabile di tipo ''Puntatore'' ad una ''Struttura'' in C, allora alla libreria ''ad hoc'' si passerà tale variabile ''Puntatore''. | <BR>Se, invece, vi è una funzione esterna della libreria esterna principale che inizializza (e quindi anche dimensionandola) nel codice Gambas la variabile di tipo ''Puntatore'' ad una ''Struttura'' in C, allora alla libreria ''ad hoc'' si passerà tale variabile ''Puntatore''. | ||
Versione delle 13:21, 25 mar 2014
Talvolta nell'uso delle risorse appartenenti a librerie esterne ci si può imbattere in Strutture molto complesse, dichiarate nei relativi file header (.h), la trascrizione delle quali in Gambas "per qualsiasi ragione" può risultare assai difficile.
Per essere sicuri di non commettere errori, una parte di queste Strutture, e comunque quelle più ostiche, potrebbe non essere dichiarata, e usata così com'è in una libreria esterna condivisa (.so) appositamente realizzata.
Più in particolare per ogni struttura che si intende usare, all'interno di tale apposita libreria condivisa (.so) vengono scritte in C alcune funzioni che verranno richiamate dall'applicativo Gambas principale.
Una di queste funzioni deve ritornare la dimensione in byte della Struttura, così da poterla allocarla con Gambas mediante la creazione di una variabile di tipo Puntatore. Questa incombenza può essere omessa se ad inizializzare la variabile di tipo Puntatore è una funzione della libreria esterna principale, di cui intendiamo sfruttare le risorse.
Le altre funzioni servono a leggere e scrivere dentro la Struttura. Ad ogni funzione, atta a leggere o scrivere nella Struttura, si passerà la relativa variabile di tipo Puntatore, creata in Gambas - come già detto - all'atto dell'allocazione, e l'eventuale valore da scrivere (se si deve scrivere in un membro della Struttura).
Indice
Conoscere la dimensione di una Struttura da utilizzare
Dunque, avremo una funzione C per ciascuna Struttura da utilizzare che ritorna la dimensione della Struttura medesima. In ordine al nome della Struttura, da inserire nella predetta funzione C, si deve precisare che:
- se la Struttura è dichiarata nel file header con la parola chiave "typedef", allora come argomento della funzione C andrà indicato il nome alias della Struttura:
int nome_funzione() { return sizeof(nome_alias_della_Struttura); }
- se, invece, la Struttura non è dichiarata con la parola chiave "typedef", allora come argomento della funzione C andrà indicato il nome della Struttura preceduto dalla parola struct:
int nome_funzione() { return sizeof(struct nome_della_Struttura); }
Come già detto, se vi è una funzione della libreria esterna principale che inizializza nel codice Gambas la variabile di tipo Puntatore, allora questa funzione C è inutile.
Se deve essere conosciuta la dimensione di un membro che punta ad una sub-Struttura, va ovviamente posta come argomento della funzione sizeof() il nome della sub-Struttura:
int nome_funzione() { return sizeof(nome_della_sub-Struttura); }
Leggere e scrivere nei membri delle Strutture
Per leggere e scrivere nei membri che ci interessano di una Struttura, si porrano nella nostra libreria ad hoc una serie di funzioni, alle quali come loro argomento si passerà una variabile di tipo Puntatore, avendo avuto l'accortezza nel codice Gambas di dimensionare oppurtunamente ed adeguatamente (ossia riservare un'area di memoria di dimensione identica a quella della Struttura da gestire) tale Puntatore mediante la funzione Alloc() nella modalità vista nel precedente paragrafo "Conoscere la dimensione di una Struttura da utilizzare".
Se, invece, vi è una funzione esterna della libreria esterna principale che inizializza (e quindi anche dimensionandola) nel codice Gambas la variabile di tipo Puntatore ad una Struttura in C, allora alla libreria ad hoc si passerà tale variabile Puntatore.
Lettura e scrittura
- Per scrivere in un membro:
void nome_funzione(nome_della_Struttura *p, int valore_da_scrivere) { p->nome_membro = valore; }
- per leggere un membro, ad esempio per ritornare un valore Integer:
int nome_funzione(nome_della_Struttura *p) { return p->nome_membro; }
Per ritornare il valore di un membro di una sub-Struttura vettoriale contenuta nella Struttura principale, si tiene conto dell'indice della sub-Struttura vettoriale prescelta:
int nome_funzione(nome_della_Struttura *p) { return p->nome_sub_Struttura_vettoriale[numero_indice].nome_membro; }
- oppure per ritornare una Stringa:
char * nome_funzione(nome_della_Struttura *p) { return p->nome_membro; }
- oppure per ritornare un puntatore ad una Struttura secondaria contenuta in un'altra Struttura principale:
nome_Struttura_secondaria * nome_funzione(nome_della_Struttura_principale *p) { return &p->nome_membro_che_punta_alla_Struttura_secondaria; }
Anche in questo caso se la Struttura non è dichiarata con la parola chiave "typedef", allora il nome della Struttura andrà preceduto dalla paola struct, oppure union se si tratta di una Union:
union nome_della_union * nome_funzione(nome_della_Struttura_principale *p) { return &p->nome_membro_che_punta_alla_Union; }
Riferimento al file header della libreria esterna principale
Ovviamente in testa al codice della nostra libreria ad hoc, va posto il tag #include "fileheader.h" riferito al file header della libreria principale, della quale si intendono utilizzare le risorse nell'applicativo Gambas, ed alle quali - tutte o solo alcune - si fa riferimento nella nostra libreria ad hoc:
// In testa il riferimento al file header della libreria principale: #include "liberiaprincipale.h"
Gestione mediante l'uso del metodo GetExternSymbol() della Classe System di Gambas
Una seconda modalità per per gestire le risorse della nostra libreria esterna .so ad hoc (creata per poter utilizzare con sicurezza le Strutture in C presenti in uno o più file header della libreria esterna principale) è quella di puntare ad alcuni simboli della nostra libreria esterna, diversi dalle funzioni, mediante il metodo System.GetExternSymbol().
La nostra speciale libreria esterna .so sarà sostanzialmente così impostata:
// In testa il riferimento al file header della libreria principale: #include "liberiaprincipale.h" // Se non v'è necessità di puntare ai particolari membri delle Strutture in C, bensì soltanto ad esse, si dichiareranno come globali le variabili del tipo di quelle Strutture da utilizzare: Struttura_Utilizzata variabile_struttura_1; // Vanno qui dichiarate anche le varibili relative alle Strutture puntate all'interno dei membri di una Struttura principle: Sub-Struttura_di_una_Struttura_Principale variabile_sub-struttura; // Quindi si dichiareranno come globali le variabili de tipo dei particolari membri delle Strutture utilizzate, di cui si intende leggere il valore contenuto: char * c; // Contiene caratteri testuali int i; // Contiene un intero long l; // Contiene un long // Una funzione consente di leggere nei membrii di una singola Struttura utilizzata: int funzione_lettura(Struttura_Utilizzata *variabile_struttura_2) { c = variabile_struttura_2->primo_membro; i = variabile_struttura_2->secondo_membro_che_punta_ad_un'altra_struttura.membro_della_sub-struttura; l = variabile_struttura_2->terzo_membro; // Caso in cui si deve passare direttamente una sub-struttura presente come membro della Struttura principale: variabile_sub-struttura = variabile_struttura_2->membro_relativo_alla_sub-struttura; return (0); }
Da precisare che i simboli, puntabili dal metodo System.GetExternSymbol() di Gambas, sono ovviamente le diverse variabili, purché poste come globali, nonché quelle poste come argomenti delle funzioni contenute dalla nostra libreria ad hoc.
Esempi pratici
Circa quanto esposto nei precedenti paragrafi del presente argomento, rinviamo a:
- questa pagina della WIKI per esempi sulla lettura di dati dai membri di una Struttura esterna in C;
- questa pagina della WIKI per esempi sulla scrittura di dati nei membri di una Struttura esterna in C.