Glib

GObject

  1. 创建两个结构体
typedef struct _PMDList PMDList;
struct  _PMDList {
        GObject parent_instance;
        PMDListNode *head;
        PMDListNode *tail;
};
 
typedef struct _PMDListClass PMDListClass;
struct _PMDListClass {
        GObjectClass parent_class;
};
  1. 创建三个函数

    2.1 ****_get_type 函数 //返回gtype类型,内部注册一次

    2.2 类初始化函数 //第一次create object 时被调用

    2.3 对象初始化函数 // 每次 create object 时被调用

    • 初始化只是赋值,不是malloc
    • get_type函数可以通过宏定义自动创建,如G_DEFINE_TYPE (PMDList, pm_dlist, G_TYPE_OBJECT);其内部将自动创建。代码如下所示,第一次调用的时候会注册这样一个类型,并且返回一个整数来表示此类型,后期调用直接使用返回类型即可,无需再次注册。
GType viewer_file_get_type (void)
{
  static GType type = 0;
  if (type == 0) { 
    const GTypeInfo info = {
      sizeof (ViewerFileClass),
      NULL,           /* base_init */
      NULL,           /* base_finalize */
      (GClassInitFunc) viewer_file_class_init,
      NULL,           /* class_finalize */
      NULL,           /* class_data */
      sizeof (ViewerFile),
      0,              /* n_preallocs */
      (GInstanceInitFunc) NULL /* instance_init */
    };
    type = g_type_register_static (G_TYPE_OBJECT,
                                   "ViewerFile",
                                   &info, 0);
  }
  return type;
}
  1. 使用对象

    3.1 g_type_init ();/* GObject 库的类型管理系统的初始化 */
    3.2 list = g_object_new (PM_TYPE_DLIST, NULL); //注意这里面两个函数,第一个参数是函数的返回值,内部会进行一次函数注册,并返回一个GType类型的对象。在glib的世界中,GType是通行证。
    3.3 g_object_unref (list); //手动给计数器-1

#ifndef PM_DLIST_H
#define PM_DLIST_H
 
#include <glib-object.h>
 
#define PM_TYPE_DLIST (pm_dlist_get_type ())
 
typedef struct _PMDListNode PMDListNode;
struct  _PMDListNode {
        PMDListNode *prev;
        PMDListNode *next;
        void *data;
};
 
typedef struct _PMDList PMDList;
struct  _PMDList {
        GObject parent_instance;
        PMDListNode *head;
        PMDListNode *tail;
};
 
typedef struct _PMDListClass PMDListClass;
struct _PMDListClass {
        GObjectClass parent_class;
};
 
GType pm_dlist_get_type (void);
 
#endif
#include "pm-dlist.h"
 
G_DEFINE_TYPE (PMDList, pm_dlist, G_TYPE_OBJECT);
 
static
void pm_dlist_init (PMDList *self)
{
        g_printf ("\tobject init\n");
 
        self->head = NULL;
        self->tail = NULL;
}
 
static
void pm_dlist_class_init (PMDListClass *klass)
{
        g_printf ("class init\n");
}
#include "pm-dlist.h"
 
int main (void)
{
        /* GObject 库的类型管理系统的初始化 */
        g_type_init ();
 
        int i;
        PMDList *list;
 
        /* 进行三次对象实例化 */
        for (i = 0; i < 3; i++){
                list = g_object_new (PM_TYPE_DLIST, NULL);
                g_object_unref (list);
        }
 
        /* 检查实例是否为 GObject 对象 */
        list = g_object_new (PM_TYPE_DLIST, NULL);
        if (G_IS_OBJECT (list))
                g_printf ("\t这个实例是一个 GObject 对象!\n");
         
        return 0;
}

参考代码

glib

source/event

The creation of a new source requires us to define at least 3 functions:

  • prepare(): Called before all the file descriptors are polled. If the source can determine that it is ready here (without waiting for the results of the poll() call), it should return TRUE. It can also return a time-out value which should be the maximum time-out (in milliseconds) which should be passed to the poll() call. The actual time-out used will be -1 if all sources returned -1, or it will be the minimum of all the timeout_values returned which were >= 0

  • check(): Called after all the file descriptors are polled. The source should return TRUE if it is ready to be dispatched.

    Time may have passed since the previous prepare function was called, so the source should be checked again.

  • dispatch() Called to dispatch the event source after it has returned TRUE in either its prepare or check function. The dispatch function is passed in a callback function and data. The callback function may be NULL if the source was never connected to a callback using g_source_set_callback(). The dispatch function should call the callback function with user_data and the additional parameters that are needed for this type of event source.

  1. prepare 中的timeout测试发现是 prepare到check的时间,check完之后会立即进入prepare
  2. check与prepare只要一个返回TRUE,dispatch 函数就执行
#include <glib.h>
gboolean callback(gpointer data)
{
    static int i = 0;
    i++;
    g_print ("timeout_callback called %d times\n",i);
    if (10 == i)
    {
        g_main_loop_quit((GMainLoop*)data);
        return FALSE;
    }

    return TRUE;
}

gboolean prepare(GSource *source,gint *timeout_)
{
    *timeout_ = -1;
    return TRUE;
}

gboolean check(GSource *source)
{
    return TRUE;
}

gboolean dispatch(GSource *source,GSourceFunc callback,gpointer user_data)
{
    if (callback(user_data))
        return TRUE;
    else
        return FALSE;
}

int main()
{
    GMainLoop *loop = NULL;
    GMainContext *context;
    GSource *source;
    int id;
	
    //create a variable of type GSourceFuncs
    GSourceFuncs SourceFuncs =
    {
        prepare,
        check,
        dispatch,
        NULL
    };
	
    //create a new source
    source = g_source_new (&SourceFuncs, sizeof(GSource));
	
    //create a context
    context = g_main_context_new ();
	
    //attach source to context
    id = g_source_attach (source,context);
	
    //create a main loop with context
    loop = g_main_loop_new (context,FALSE);
 
    //set the callback for this source
    g_source_set_callback (source,callback,loop,NULL);
	
    g_main_loop_run (loop);
    g_main_loop_unref (loop);
	
    return 0;
}

https://blog.csdn.net/u010009623/article/details/53101492

thread & mutex

static GMutex *mutex = NULL;
static gboolean t1_end = FALSE;
static gboolean t2_end = FALSE;
typedef struct _Arg Arg;
struct _Arg
{
    GMainLoop* loop;
    gint max;
};
void run_1(Arg *arg)
{
    int i ;
   
    for(i=0; i<arg->max;)
    {
        if(g_mutex_trylock(mutex))
        {
            g_print("%d : thread 1 locked mutex \n", i);
            g_usleep(1000000);
            i++;
            g_mutex_unlock(mutex);
        }
    }
    t1_end = TRUE;
}
void run_2(Arg *arg)
{
    int i;
    for(i=0; i<arg->max;)
    {
        if(g_mutex_trylock(mutex))
        {
            g_print("%d : thread 2 locked mutex \n", i);
            g_usleep(10);
            i++;
            g_mutex_unlock(mutex);
        }
    }
    t2_end = TRUE;
}
void run_3(Arg *arg)
{
    for(;;)
    {
        if(t1_end && t2_end)
        {
            g_main_loop_quit(arg->loop);
            break;
        }
    }
}
int    main(int argc, char *argv[])
{
    GMainLoop *mloop;
    Arg *arg;
   
    if(!g_thread_supported())
        g_thread_init(NULL);
    mloop = g_main_loop_new(NULL, FALSE);
   
    arg = g_new(Arg, 1);
    arg->loop = mloop;
    arg->max = 11;
       
    mutex = g_mutex_new();
    g_thread_create(run_1, arg, TRUE, NULL);
    g_thread_create(run_2, arg, TRUE, NULL);
    g_thread_create(run_3, arg, TRUE, NULL);
   
    g_main_loop_run(mloop);
    g_print("thread 3 exit \n");
    g_mutex_free(mutex);
    g_print("free mutex \n");
    g_free(arg);
    g_print("free all memory\n");
}

signal

https://developer.gnome.org/gobject/stable/howto-signals.html

  1. 新建一个signal object //在class init中
  2. 关联到某个callback
  3. emit signal

static
void pm_dlist_class_init (PMDListClass *klass)
{
        g_printf ("class init\n");
        mysignal = g_signal_newv ("changed",
                 G_TYPE_FROM_CLASS (klass),
                 G_SIGNAL_RUN_LAST | G_SIGNAL_NO_RECURSE | G_SIGNAL_NO_HOOKS,
                 NULL /* closure */,
                 NULL /* accumulator */,
                 NULL /* accumulator data */,
                 g_cclosure_marshal_VOID__VOID,
                 G_TYPE_NONE /* return_type */,
                 0     /* n_params */,
                 NULL  /* param_types */);
}

void changed_event()
{
  g_print("triger signal \n");
}

int main (void)
{
        /* GObject 库的类型管理系统的初始化 */
        g_type_init ();
 
        int i;
        PMDList *list;

        list = g_object_new (PM_TYPE_DLIST, NULL);
        g_signal_connect (list, "changed", G_CALLBACK (changed_event), NULL);
        g_signal_emit (list, mysignal, 0 /* details */);

        return 0;
}
GType viewer_file_get_type (void)
{
  static GType type = 0;
  if (type == 0) {
    const GTypeInfo info = {
      sizeof (ViewerFileClass),
      NULL,           /* base_init */
      NULL,           /* base_finalize */
      (GClassInitFunc) viewer_file_class_init,
      NULL,           /* class_finalize */
      NULL,           /* class_data */
      sizeof (ViewerFile),
      0,              /* n_preallocs */
      (GInstanceInitFunc) NULL /* instance_init */
    };
    type = g_type_register_static (G_TYPE_OBJECT,
                                   "ViewerFile",
                                   &info, 0);
  }
  return type;
}
  • 2
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值