Linux. Полное руководство.

23.2. Библиотека Glib.

23.2.1. Стандартные типы данных библиотеки Glib.

Библиотека Glib содержит типы данных, аналогичные типам данных языка С, а также такие структуры, как деревья, списки; функции для работы с памятью и обработки ошибок. Это сделано для того, чтобы ваше приложение могло быть легко портировано на другую платформу. Например, на одних компьютерах тип int может быть 32-разрядным, а на других — 64-разрядным (это зависит от архитектуры центрального процессора), А если вы используете тип gint, объявленный в библиотеке Glib, то можете дальше разрабатывать свое приложение и не беспокоиться о том, как оно будет работать на RISC-машине под управлением Windows NT. В таблице 23.1 перечислены типы данных библиотеки GLib, которые соответствуют типам данных С.

Таблица соответствия типов данных Glib и С Таблица 23.1.

Тип данных С Тип данных Glib
char gchar
short gshort
long glong
int gint
bool gboolean
unsigned char guchar
unsigned short gushort
unsigned long gulong
unsigned int guint
float gfloat
double gdouble
long double gldouble
void* gpointer

Для использования этих типов данных, как и прочих возможностей библиотеки Glib, необходимо подключить заголовочный файл glib.h.

23.2.2. Функции для работы с памятью.

Функции для работы с памятью библиотеки Glib выполняют те же действия, что и соответствующие им функции языка С. Вот их прототипы:

Gpointer g_malloc(gulong size);

Gpointer g_realloc(gpointer mem, gulong size);

Void g_free(gpointer mem);

23.2.3. Строки и Glib.

Библиотека Glib содержит довольно много функций для работы со строками, но я перечислю лишь самые с моей точки зрения интересные (таблица 23.2).

Некоторые строковые функции библиотеки Glib Таблица 23.2.

Прототип Описание
gchar* g_strchug(gchar* s) Функция удаляет все пробелы в строке s, стоящие в начале строки (до первого печатного символа). Данная функция может пригодиться для контроля введенной пользователем информации
gchar* g_strchomp(gchar* s) Функций удаляет все пробелы в строке s, стоящие в конце строки
gchar* g_strstrip(gchar* s) Функция удаляет пробелы а начале и в конце строки
void g_strdown(gchar* s) Функция переводит все буквы строки s в нижний регистр
void g_strup(gchar* s) Функция переводит все буквы строки s в верхний регистр
void g_strreverse(gchar* s) Функция преобразовывает прописные буквы в строчные и наоборот

23.2.4. Списки.

Библиотека Glib содержит средства для работы с одно- и двусвязными списками. Особенность двусвязного списка заключается в том, что по нему можно перемещаться в обоих направлениях — назад и вперед. В файле gslist.h (Glib Single List) описаны средства для работы с односвязными списками, а в файле glist.h — для работы с двусвязным списком.

Вот структуры односвязного и двусвязного списков:

// односвязный список.

Typedef struct _GSList GSList;

Struct _GSList {

 gpointer data;

 GSList *next; // указатель на следующий элемент списка.

};

// двусвязный список.

Typedef struct _GList GList;

Struct _GList {

 gpointer data;

 GList *next; // указатель на следующий элемент списка.

 GList *prev; // указатель на предыдущий элемент списка.

};

Поле data предназначено для хранения данных списка, причем они могут быть любого типа, ведь gpointer — это тип void*.

Работать со списками очень просто. Для начала нужно объявить список:

GList *list = NULL;

GSList *slist = NULL;

Затем добавить элементы в список. Это можно сделать с помощью двух функций — g_list_append() или g_slist_prepend() — в зависимости от используемого типа списка:

Gchar *el = g_strdup("это первый элемент");

List = g_list_append(list, el);

Функции g_list_append() и g_slist_append() добавляют элемент в конец списка. Если вы хотите добавить элемент в начало списка, нужно использовать функции:

G_list_prepend(GList *list, gpointer data);

G_slist_prepend{GSList *list, gpointer data);

Чтобы вставить новый элемент в определенную позицию, нужно использовать функции:

GList *g_list_insert(GList *list, gpointer data, gint position);

GSList *g_slist_insert(GSList *list, gpointer data, gint position);

Здесь position — это номер элемента, перед которым нужно вставить новый элемент. Если position=0, то элемент будет добавлен в начало списка, то есть перед бывшим первым элементом.

Для удаления элемента используются функции:

GList *g_list_remove(GList *list, gpointer data);

GSList *g_slist_remove(GSList *list, gpointer data);

Для передвижения по списку используются функции:

G_list_next(), g_slist_next() — на "шаг" вперед.

G_list_prev() — назад.

Вот небольшой пример работы со списком — вывод на консоль всех его элементов:

// double_list должен быть определен и содержать элементы.

GList *list = double_list;

While (list!=NULL) {

 printf("%s\n",list->data);

 list = g_list_next(list);

}

По окончании работы со списком не забудьте освободить память:

Void g_list_free(GList *list);

Void g_slist_free(GSList *slist);

Для сортировки списка используется функция:

GSList *g_slist_sort(GSList * slist, GCompareFunc f);

Первый параметр — это список, который нужно отсортировать. Второй — это функция сравнения двух элементов. Вот ее прототип:

Typedef gint (*GCompareFunc) (gconstpointer a, gconstpointer b); Данную функцию вы должны написать самостоятельно. Она должна принимать два параметра и возвращать целое значение:

♦ если a<b, то -1 (точнее, любое число меньше 0);

♦ если a==b, то 0;

♦ если a>b, то 1 (любое число больше 0).

Библиотека Glib также содержит средства для работы с деревьями — как бинарными, так и произвольными, но мы эти средства рассматривать не будем.

23.2.5. Таймеры в Glib.

Библиотека Glib позволяет использовать таймеры в наших программах.

Для этого нужно:

♦ подключить заголовочный файл gtimer.h;

♦ создать таймер функцией GTimer *g_timer_new();

♦ запустить таймер функцией g_timer_start(GTimer *timer);

♦ узнать время, отсчитанное таймером — g_timer_elapsed();

♦ при необходимости перезапустить таймер с помощью функции g_timer_reset(GTimer *timer);

♦ остановить таймер функцией g_timer_stop(GTimer * timer);

♦ уничтожить таймер — g_timer_destroy(GTimer *timer).

Стоит остановиться подробнее лишь на функции g_timer_elapsed(GTimer *timer, gulong *mcs). Данная функция возвращает число секунд, отсчитанное таймером. По адресу указателя *mcs записывается число микросекунд.

Пример использования таймера представлен в листинге 23.1.

Листинг 23.1. Использование таймера.

#include <stdio.h>

#include <glib.h>

#include <gtimer.h>

Int main() {

 double sec;

 gulong ms;

 int i;

 GTimer *timer = g_timer_new();

 printf("Данный цикл будет работать не более 10 секунд\n");

 g_timer_start(timer);

 for (i=1; i>0;) {

  sec = g_timer_elapsed(timer,&ms);

  if (sec >=10) {

   g_timer_stop(timer);

   printf("Таймер остановлен. Мкс: %d\n",ms);

   break;

  }

 }

 g_timer_destroy(timer);

 return 0;

}