Gestire con sicurezza le Strutture esterne
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.
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 campo della Struttura).
Dunque, avremo una funzione C per ciascuna Struttura da utilizzare che ritorna la dimensione della Struttura medesima:
int nome_funzione() { return sizeof(nome_della_Struttura); }
Se deve essere conosciuta la dimensione di un campo 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); }
e una serie di funzioni per leggere e scrivere nei campi che interessano.
Per scrivere in un campo:
void nome_funzione(nome_della_Struttura *p, int valore_da_scrivere) { p->nome_campo = valore; }
e per leggere un campo, ad esempio per ritornare un valore Integer:
int nome_funzione(nome_della_Struttura *p) { return p->nome_campo; }
oppure per ritornare una Stringa:
char * nome_funzione(nome_della_Struttura *p) { return p->nome_campo; }
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_campo_che_punta_alla_Struttura_secondaria; }
Riferimento al file header della libreria esterna principale
Ovviamente in testa al codice della nostra libreria ad hoc, va posta 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.
Gestione mediante l'uso del metodo GetExternSymbol() della Classe System di Gambas
Per gestire le risorse della libreria esterna .so ad hoc, sarà possibile puntare ad alcuni simboli di quella libreria esterna, diversi dalle funzioni, mediante il metodo System.GetExternSymbol().
La nostra speciale libreria 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 campi 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 campi di una Struttura principle: Sub-Struttura_di_una_Struttura_Principale variabile_sub-struttura; // Quindi si dichiareranno come globali le variabili de tipo dei particolari campi 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 campi di una singola Struttura utilizzata: int funzione_lettura(Struttura_Utilizzata *variabile_struttura_2) { c = variabile_struttura_2->primo_campo; i = variabile_struttura_2->secondo_campo_che_punta_ad_un'altra_struttura.campo_della_sub-struttura; l = variabile_struttura_2->terzo_campo; // Caso in cui si deve passare direttamente una sub-struttura presente come campo della Struttura principale: variabile_sub-struttura = variabile_struttura_2->campo_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
Per gli esempi pratici, relativi ad entrambi i paragrafi del presente argomento, rinviamo a questa pagina della WIKI.