INTRODUZIONE A GLIB

 

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.

 

Torna all'indice