1 共用体
我C语言使用union比较少,所以先回顾一下共用体的知识。结构体的各个成员会占用不同的内存,互相之间没有影响;而共用体的所有成员占用同一段内存,修改一个成员会影响其余所有成员。例如:
union _data
{
guint32 n;
guint16 m;
guint8 ch;
};
共享内存结构如图
如果先设置 m = 0x00F0,在设置 ch = 0x0F ,结果不是m = 0x00FF,而是 m = 0x000F,赋值某一个成员,都会清空全部内存,在赋值这一成员。
2 GValue
C语言里,通用数据类型我们一般用void *以表示任何类型的数据。GObject为了解决多语言交互问题,所以必须设计出一套能容纳任何数据类型的通用数据类型。以便于在不同的编程语言你之间进行数据转换操作。这个数据类型就是GValue。
以下是GValue结构体信息,共占用24字节内存,GType是无符合长整形8字节。
- 创建结构体时候必须用零填充。
- 必须初始化类型。
- 已初始化过的GValule,要初始化成其他类型,必须使用重置g_value_unset
/**
Compile:
gcc Gvalue.c `pkg-config --cflags --libs glib-2.0 gobject-2.0`
*/
#include<glib.h>
#include<glib/gprintf.h>
#include<glib-object.h>
#include<stdlib.h>
static void
string2int (const GValue *src_value,
GValue *dest_value)
{
const gchar *value = g_value_get_string (src_value);
int i = atoi(value);
g_value_set_int (dest_value, i);
}
int
main (int argc, char *argv[])
{
/*Gvalues 一定要被初始化*/
GValue a = G_VALUE_INIT;
GValue b = G_VALUE_INIT;
g_type_init();
/* g_assert判断是否是G_VALUE_HOLDS_STRING字符串类型
* 因为现在和没有初始化类型,G_VALUE_HOLDS_STRING(&a) 等于 0
*/
g_assert(!G_VALUE_HOLDS_STRING(&a));
/*把变量a初始化为字符串类型*/
g_value_init(&a, G_TYPE_STRING);
g_assert(G_VALUE_HOLDS_STRING(&a));
g_value_set_string(&a, "Hello World");
g_printf("%s\n", g_value_get_string(&a));
/* 必须重置变量a恢复到原始状态 */
g_value_unset(&a);
/* 必须初始化成uint64,否则报错 */
g_value_init(&a, G_TYPE_INT);
g_value_set_uint64(&a, 12);
g_printf("%ld\n", g_value_get_uint64(&a));
g_value_init(&b, G_TYPE_STRING);
/g_assert(g_value_type_transformable(G_TYPE_INT, G_TYPE_STRING));
g_value_transform(&a, &b);
g_printf("%s\n", g_value_get_string(&b));
/* An STRINT is not transformable to INT */
if (g_value_type_transformable (G_TYPE_STRING, G_TYPE_INT)) {
g_printf ("Can transform string to int\n");
} else
g_printf ("Can Not transform string to int\n");
/* Attempt to transform it again using a custom transform function */
g_value_set_string(&b, "43");
g_value_register_transform_func (G_TYPE_STRING, G_TYPE_INT, string2int);
g_value_transform (&b, &a);
g_printf ("%d\n", g_value_get_int(&a));
return 0;
}
struct _GValue
{
/*< private >*/
GType g_type;
/* public for GTypeValueTable methods */
union {
gint v_int;
guint v_uint;
glong v_long;
gulong v_ulong;
gint64 v_int64;
guint64 v_uint64;
gfloat v_float;
gdouble v_double;
gpointer v_pointer;
} data[2];
};
3 g_assert
如果g_assert(FALSE)就会抛出异常,终止程序运行,反则g_assert(TRUE)正常。