Allo stesso tempo si è offerto allo sviluppatore un potente e completo framework per la progettazione e costruzione di applicazioni basate su standard oramai affermati e facilmente integrabili con i più diffusi linguaggi di programmazione attualmente disponibili nel mondo Unix.
Gnome e Gtk sono nate per creare uno standard free (open source) per scrivere applicazioni grafiche uniformi per sistemi UNIX.
Chiunque può usare le librerie Gtk e la infrastruttura Gnome senza dover pagare diritti o sottostare a vincoli dei produttori.
Visto il rapido sviluppo di questi strumenti ho deciso di scrivere un paio di articoli in materia corredati da un tutorial integralmente in italiano che traduce e riassume essenzialmente quello ufficiale fornito a corredo delle librerie. Struttura di un'applicazione Gnome
Abbiamo già evidenziato la differenza tra Gnome e Gtk+ per chi non l'avesse ancora chiara rimandiamo alla lettura dell'articolo che si trova nella specifica sezione.Introduzione a Glib.
Qui basti rilevare che Gnome comprende Gtk+ quindi un'applicazione Gnome comprenderà automaticamente le librerie Gtk+ che non sarà neanche necessario richiamare con l'include in quanto automaticamente comprese nell'header "gnome.h".
Come abbiamo già messo in rilievo sia Gtk+ che Gnome sono dipendenti dalla libreria Glib.
Descriveremo quindi alcune delle caratteristiche più comunemente usate in applicazioni Gtk+ e Gnome.
Glib è una libreria C di utilità portabilità e utilità generale che offre molteplici facilitazioni e sostituti ai costrutti C standard. Ha un unico file header "glib.h" che potete facilmente consultare per una descrizione completa.
Definizioni dei tipi fondamentali:
Anzichè utilizzare i tipi standard del linguaggio C (int, long etc.) glib definisce i propri. Questi si rivelano utili in molti casi. Ad esempio abbiamo la garanzia che gint32 sia a di 32 bit, proprietà che nessun tipo standard C può assicurare.
Ecco l'elenco dei tipi definiti da glib e, dove esiste, il corrispondente standard C.
char gchar;
short gshort;
long glong;
int gint;
char gboolean;
unsigned char guchar;
unsigned short gushort;
unsigned long gulong;
unsigned int guint;
float gfloat;
double gdouble;
long double gldouble;
void* gpointer;
gint8
guint8
gint16
guint16
gint32
guint32
Macro frequentemente utilizzate:
Glib definisce inoltre alcune Macro comunemente utilizzate in programmi C come:
MAX(a, b);
MIN(a, b);
ABS(x);
CLAMP(x, low, high);
TRUE
FALSE
NULL
Il significato dovrebbe essere chiaro, MIN e MAX restituiscono il valore più piccolo o più grande dei loro argomenti, ABS restituisce il valore assoluto. CLAMP restituisce x se x sta tra low e high; restituisce low se x è sotto l'intervallo; restituisce invece high se x è sopra.
Gestione della memoria:
Per quanto riguarda la gestione della memoria glib rimpiazza le funzioni malloc() e free() con g_malloc() e g_free().
gpointer g_malloc( gulong size );
gpointer g_malloc0( gulong size );
gpointer g_realloc( gpointer mem,
gulong size );
void g_free( gpointer mem );
void g_mem_profile( void );
void g_mem_check( gpointer mem );
Queste supportano diversi modi di debugging e profiling della memoria e diverse facilitazioni.
Ad esempio g-malloc() restiruisce sempre un gpointer e non c'è quindi bisogno di un cast; inoltre termina il programma se la malloc interna fallisce quindi non si deve controllare se ritorna un NULL e ancora restituisce NULL nel caso in cui la dimensione richiesta è 0.
g_free() inoltre ignora tutti i puntatori NULL che gli vengono passati.
Stringhe:
Glib fornisce molte funzioni di manipolazione delle stringhe; alcune sono esclusive di glib, altre servono esclusivamente per risolvere problemi di portabilità. Tutte si integrano perfettamente con le routine di allocazione della memoria di glib. Inoltre glib definisce il tipo GString che è simile alla stringa standard del C ma che cresce automaticamente. La stringa viene terminata con NULL e fornisce una importante protezione dagli errori di buffer overflow. La definizione di GString è:
struct GString
{
gchar *str; /* Punta al valore \0 di terminazione della stringa */
gint len; /* Lunghezza corrente */
};
Ci sono molte operazioni possibili con GString:
GString *g_string_new( gchar *init );
Costruisce una GString copiando lo string value dell'inizio nella GString e ritorna un puntatore.
Può essere usato come argomento NULL per una GString inizialmente vuota.
void g_string_free( GString *string,
gint free_segment );
Libera la memoria della GString e dei dati contenuti.
GString *g_string_assign( GString *lval,
const gchar *rval );
Copia i caratteri da rval in lval, distruggendo il contenuto precedente di lval.
Il resto delle funzioni sono abbastanza ovvie da non ricevere alcun commento:
GString *g_string_truncate( GString *string,
gint len );
GString *g_string_append( GString *string,
gchar *val );
GString *g_string_append_c( GString *string,
gchar c );
GString *g_string_prepend( GString *string,
gchar *val );
GString *g_string_prepend_c( GString *string,
gchar c );
void g_string_sprintf( GString *string,
gchar *fmt,
...);
void g_string_sprintfa ( GString *string,
gchar *fmt,
... );
Timer:
Glib fornisce inoltre delle utili funzioni Timer utili ad esempio per saepre quanto tempo è passato. Prima si crea un nuovo timer con g_timer_new(). Poi con g_timer_start() e g_timer_stop() avviamo e fermiamo il processo e con g_timer_elapsed() eterminiamo il tempo trascorso.
GTimer *g_timer_new( void );
void g_timer_destroy( GTimer *timer );
void g_timer_start( GTimer *timer );
void g_timer_stop( GTimer *timer );
void g_timer_reset( GTimer *timer );
gdouble g_timer_elapsed( GTimer *timer,
gulong *microseconds );
Funzioni di utilità generale:
GLib fornisce anche funzioni di utilità generale:
gchar *g_strdup( const gchar *str );
Copia il contenuto della stringa originale in una nuova allocata in memoria e ritorna un puntatore ad essa.
gchar *g_strerror( gint errnum );
ritorna il seguente output "nome programma:functione fallita:file o breve descrizione:strerror"
void g_error( gchar *format, ... );
Stampa un messaggio di errore. Il formato è quello di printf, ma antepone "** ERROR **: " al messaggio ed esce dal programma.
void g_warning( gchar *format, ... );
Come la precedente, ma antepone "** WARNING **: ", e non esce dal programma.
void g_message( gchar *format, ... );
Stampa "message: " anteposto alla stringa che gli viene passata.
void g_print( gchar *format, ... );
Sostituto di printf().
Strutture di dati:
Glib fornisce e implementa molte strutture di dati comunemente usate, così non dovete reinventare la ruota ogni volta che vi serve una lista collegata. Questa introduzione illustra le liste single-linked e double-linked ma sono disponibili molte altre strutture tra le quali alberi binari, alberi n-ari, tabelle hash etc..
Liste double-linked.
Non c'e' una funzione specifica per creare una lista. Basta creare una variabile di tipo GList* e settare il suo valore a NULL; NULL è considerato come una lista vuota.
Per aggiungere elementi alla lista si può usare le routine g_list_append(), g_list_prepend(), g_list_insert(), g_list_insert_sorted(). In tutti i casi esse accettano un puntatore all'inizio della lista e ritornano egualmente il nuovo puntatore all'inizio della lista.
GList *g_list_append( GList *list,
gpointer data );
Aggiunge un nuovo elemento alla fine della lista.
GList *g_list_prepend( GList *list,
gpointer data );
Aggiunge un nuovo elemento all'inizio della lista.
GList *g_list_insert( GList *list,
gpointer data,
gint position );
Aggiunge un nuovo elemento alla posizione specificata.
GList *g_list_remove( GList *list,
gpointer data );
Rimuove l'elemento corrispondente al vaore "data".
void g_list_free( GList *list );
Libera tutta la memoria usata da GList.
Ci sono molti altre funzioni relative alle double-linked list. Consultare la documentazione relativa per maggiori spiegazioni. Si riportano di seguito comunque alcune delle funzioni più usate:
GList *g_list_remove_link( GList *list,
GList *link );
GList *g_list_reverse( GList *list );
GList *g_list_nth( GList *list,
gint n );
GList *g_list_find( GList *list,
gpointer data );
GList *g_list_last( GList *list );
GList *g_list_first( GList *list );
gint g_list_length( GList *list );
void g_list_foreach( GList *list,
GFunc func,
gpointer user_data );
Liste single-linked.
Molte delle funzioni per le single-list sono identiche alle precedenti ecco la lista di quelle più usate:
GSList *g_slist_append( GSList *list,
gpointer data );
GSList *g_slist_prepend( GSList *list,
gpointer data );
GSList *g_slist_insert( GSList *list,
gpointer data,
gint position );
GSList *g_slist_remove( GSList *list,
gpointer data );
GSList *g_slist_remove_link( GSList *list,
GSList *link );
GSList *g_slist_reverse( GSList *list );
GSList *g_slist_nth( GSList *list,
gint n );
GSList *g_slist_find( GSList *list,
gpointer data );
GSList *g_slist_last( GSList *list );
gint g_slist_length( GSList *list );
void g_slist_foreach( GSList *list,
GFunc func,
gpointer user_data );
Esistono comunque numerose altre features offerte da Glib, Si consiglia di consultare i sorgenti o la manualistica relativa per una più completa descrizione.
Nessun commento:
Posta un commento
Non inserire link cliccabili altrimenti il commento verrà eliminato. Metti la spunta a Inviami notifiche per essere avvertito via email di nuovi commenti.