安装备忘:
由于服务器上的python是2.4.2,而最新的 glib 2.34 需要 python2.5,简便起见,选择了glib-2.26.1.tar.gz 安装。
安装之前,如果gettext版本较低,要升级到0.17
代码编译
示例文件为glib.c
export PKG_CONFIG_PATH=/usr/local/glib-2.26.1/lib/pkgconfig/:$PKG_CONFIG_PATH
export LD_LIBRARY_PATH=/usr/local/glib-2.26.1/lib/:$LD_LIBRARY_PATH
gcc glib.c -Wall `pkg-config --libs --cflags glib-2.0`
接口参考文献:
http://developer.gnome.org/glib/2.26/
针对hashtable系统提供了一些便捷方法:
/* Hash Functions
*/
gboolean g_str_equal (gconstpointer v1,
gconstpointer v2);
guint g_str_hash (gconstpointer v);
gboolean g_int_equal (gconstpointer v1,
gconstpointer v2);
guint g_int_hash (gconstpointer v);
gboolean g_int64_equal (gconstpointer v1,
gconstpointer v2);
guint g_int64_hash (gconstpointer v);
gboolean g_double_equal (gconstpointer v1,
gconstpointer v2);
guint g_double_hash (gconstpointer v);
下面是文件内容,依次尝试了不同容器的各种方法:
#include <string.h>
#include <stdio.h>
#include <stdlib.h>
#include "glib.h"
void show_tree(const gchar* fname) {
int i;
int indent;
int length = strlen(fname);
for (i = 0; i < length; i++) {
g_print("%c", fname[i]);
}
g_print("\n");
for (i = 0, indent = 0; i < length; i++) {
if(fname[i] != G_DIR_SEPARATOR)
g_print("%c", fname[i]);
else {
indent++;
switch(indent) {
case 1 : g_print("the dir "); break;
case 2 : g_print(" contains "); break;
default : g_print(", which contains ");
}
}
}
g_print("\n");
}
gint item_compare(gconstpointer v1, gconstpointer v2) {
return -strcmp((char *)v1, (char *)v2);
}
void item_visit(gpointer listdata, gpointer userdata) {
g_print("%s -> %s\n", (char *)userdata, (char *)listdata);
}
void test_list() {
GSList *mylist = NULL;
mylist = g_slist_append(mylist, "alex");
mylist = g_slist_append(mylist, "billy");
mylist = g_slist_append(mylist, "coco");
mylist = g_slist_prepend(mylist, "3");
mylist = g_slist_prepend(mylist, "2");
mylist = g_slist_prepend(mylist, "1");
mylist = g_slist_insert(mylist, "insert", 1);
GSList *item;
for(item = mylist; item != NULL; item = g_slist_next(item)) {
g_print("mylist -> %s\n", (gchar *)(item->data));
}
mylist = g_slist_sort(mylist, (GCompareFunc)item_compare);
g_slist_foreach(mylist, (GFunc)item_visit, "mylist item");
g_print("mylist header is : %s\n", (char *)mylist->data);
g_slist_free(mylist);
}
typedef struct person {
char *surname;
char *name;
} person;
gint compare_item(gpointer v1, gpointer v2) {
person *p1 = (person *)v1;
person *p2 = (person *)v2;
char n1[100] = {'\0'};
char n2[100] = {'\0'};
sprintf(n1, "%s%s", p1->surname, p1->name);
sprintf(n2, "%s%s", p2->surname, p2->name);
return strcmp(n1, n2);
}
gint traverse_tree(gpointer key, gpointer value, gpointer data) {
person *p = (person *)key;
g_print("[%s]%s:%s => %s\n", (char *)data, p->surname, p->name, (char *)value);
return FALSE;
}
void test_tree() {
GTree *mytree;
mytree = g_tree_new((GCompareFunc)compare_item);
person p1;
p1.surname = strdup("zhou");
p1.name = strdup("yu");
g_tree_insert(mytree, &p1, "ubuntu");
person p2;
p2.surname = strdup("zhou");
p2.name = strdup("runfa");
g_tree_insert(mytree, &p2, "window");
person p3;
p3.surname = strdup("zhang");
p3.name = strdup("guorong");
g_tree_insert(mytree, &p3, "redhat");
g_tree_traverse(mytree, traverse_tree, G_IN_ORDER, "in");
g_tree_traverse(mytree, traverse_tree, G_PRE_ORDER, "pre");
g_tree_traverse(mytree, traverse_tree, G_POST_ORDER, "post");
person ps;
ps.surname = strdup("zhang");
ps.name = strdup("guorong");
char *psvalue = (char *)g_tree_lookup(mytree, &ps);
g_print("lookup p[%s:%s] -> %s\n", ps.surname, ps.name, psvalue);
/**
gpointer orig_key;
gpointer orig_value;
g_tree_lookup_extended(mytree, &ps, &orig_key, &orig_value);
person *po = (person *)orig_key;
char *vo = (char *)orig_value;
g_print("lookup_extended p[%s:%s] -> %s\n", po->surname, po->name, vo);
//po == &p3 [zhang:guorong]
//free(p3.surname);
//free(p3.name);
free(po->surname);
free(po->name);
*/
free(p1.surname);
free(p1.name);
free(p2.surname);
free(p2.name);
free(p3.surname);
free(p3.name);
free(ps.surname);
free(ps.name);
g_tree_destroy(mytree);
}
guint hash_code(gconstpointer key) {
char *k = (char *)key;
guint h;
int i, len;
for(i = 0, len = strlen(k); i < len; i++) {
h = 31 * h + k[i];
}
printf("[hash_code] %s -> %d\n", k, h);
return h;
}
gboolean hash_equal(gconstpointer key1, gconstpointer key2) {
char *k1 = (char *)key1;
char *k2 = (char *)key2;
printf("[hash_equal] %s -> %s\n", k1, k2);
return strcmp(k1, k2) == 0 ? TRUE : FALSE;
}
void key_destroy(gpointer data) {
//do nothing
printf("[key_destroy] : %s\n", (char *)data);
}
void value_destroy(gpointer data) {
person *p = (person *)data;
printf("[value_destroy] : %s %s\n", p->surname, p->name);
free(p->surname);
free(p->name);
}
void test_hashtable() {
GHashTable *mytree;
//mytree = g_hash_table_new_full((GHashFunc)hash_code, (GEqualFunc)hash_equal, (GDestroyNotify)key_destroy, (GDestroyNotify)value_destroy);
//mytree = g_hash_table_new((GHashFunc)hash_code, (GEqualFunc)hash_equal);
//this is convenience provided by ghash.h
mytree = g_hash_table_new_full((GHashFunc)g_str_hash, (GEqualFunc)g_str_equal, (GDestroyNotify)key_destroy, (GDestroyNotify)value_destroy);
person p1;
p1.surname = strdup("zhou");
p1.name = strdup("yu");
g_hash_table_insert(mytree, "ubuntu", &p1);
person p2;
p2.surname = strdup("zhou");
p2.name = strdup("runfa");
g_hash_table_insert(mytree, "window", &p2);
person p3;
p3.surname = strdup("zhang");
p3.name = strdup("guorong");
g_hash_table_insert(mytree, "redhat", &p3);
person *ps = (person *)g_hash_table_lookup(mytree, "window");
g_print("lookup -> %s : %s\n", ps->surname, ps->name);
g_hash_table_destroy(mytree);
}
gint main(gint argc, gchar *argv[]) {
show_tree("/usr/local/test.txt");
test_list();
test_tree();
test_hashtable();
return 0;
}