• [转] DBus学习(四):基础小例子(同步和异步)


    From: http://blog.csdn.net/flowingflying/article/details/5418180 

    从Tutorial中学习基本概念后,进入实战阶段,通过学习,我们给出连个小例子,同步例子和异步例子。

    类型和GType的映射

      在D-Bus编程中,基础类型和GType的映射表格如下。在后面的程序小例子中我们会看到具体如何对应。

    D-Bus basic type GType Free function Notes
    BYTE G_TYPE_BOOLEAN    
    INT16 G_TYPE_INT   Will be changed to a G_TYPE_INT16 once GLib has it
    UINT16 G_TYPE_UINT   Will be changed to a G_TYPE_UINT16 once GLib has it
    INT32 G_TYPE_INT   Will be changed to a G_TYPE_INT32 once GLib has it
    UINT32 G_TYPE_UINT   Will be changed to a G_TYPE_UINT32 once GLib has it
    INT64     G_TYPE_GINT64
    UINT64 G_TYPE_GUINT64    
    DOUBLE G_TYPE_DOUBLE    
    STRING G_TYPE_STRING g_free  
    OBJECT_PATH DBUS_TYPE_G_PROXY g_object_unref The returned proxy does not have an interface set; use dbus_g_proxy_set_interface to invoke methods

      在D-Bus编程中,container类型和GType的映射表格如下:

    D-Bus type signature Description GType C typedef Free function Notes
    as Array of strings G_TYPE_STRV char ** g_strfreev  
    v Generic value container G_TYPE_VALUE GValue * g_value_unset The calling conventions for values expect that method callers have allocated return values; see below.
    a{ss} Dictionary mapping strings to strings

    DBUS_TYPE_G_STRING_
    STRING_HASHTABLE

    GHashTable * g_hash_table_destroy  

    Makefile

      在D-Bus中,使用了dbus-1 dbus-glib-1 glib-2.0(以Moblin 2.1为例)。Makefile的例子如下:

    CC     = gcc 
    CFLAGS += -Wall -g `pkg-config dbus-1 dbus-glib-1 glib-2.0 --cflags` 
    LIBS   += -Wall -g `pkg-config dbus-1 dbus-glib-1 glib-2.0 --libs`

    TARGET  = sample 
    OBJ    = $(TARGET).o

    all: $(TARGET)

    %o: %c 
        $(CC) $(CFLAGS) -c $< -o $@

    $(TARGET): $(OBJ) 
        $(CC) $(LIBS) -o $(TARGET) $(OBJ)

    同步的例子

      同步即程序发出method call消息,等待method_return消息。下面是一个小例子,如果我们用dbus-send命令,可以使用:

    dbus-send --session --print-reply --type=method_call --dest=org.freedesktop.Notifications / org.freedesktop.DBus.Introspectable.Introspect

      在上一次学习中学习过。它的返回GType类型为G_TYPE_STRING,在C程序中对应char *。

    #include <stdio.h> 
    #include <stdlib.h> 
    #include <dbus/dbus-glib.h>

    int main( int argc , char ** argv) 

        GError * error; 
        DBusGConnection * connection; 
        DBusGProxy    * proxy; 
        char    * string;

       /* GType初始化 */ 
       g_type_init(); 
        error = NULL;

        /* dbus_g_bus_get用来建立连接,这里和session bus连接,也可以通过DBUS_BUS_SYSTEM与系统总线连接*/ 
        connection = dbus_g_bus_get (DBUS_BUS_SESSION, & error); 
        if(connection == NULL){ 
            g_printerr ("Failed to open connection to bus : %s/n",error->message); 
            g_error_free( error); 
            exit( 1 ); 
        }

        /* Create a proxy object用来代表远端org.freedesktop.Notifications是系统带有的,可以使用DBUS_INTERFACE_INTROSPECTABLE等定义来标识它*/ 
        proxy = dbus_g_proxy_new_for_name (connection, 
                                     "org.freedesktop.Notifications" 
    /* service */ ,  
                                     "/"
     /* path */ 
                                     
    "org.freedesktop.DBus.Introspectable" /* interface,可以使用宏定义DBUS_INTERFACE_INTROSPECTABLE */ );

        error = NULL;

        /* 采用同步方式,第二个参数是method,第三个参数是error,后面是不定长的参数,显示输入,后为输出,以G_TYPE_INVALID标识接收,每个参数由GType类型和存贮参数值的地址构成。在这个例子中,输入没有参数,输入有一个参数,是string*/ 
        if( !dbus_g_proxy_call (proxy,"Introspect",&error, G_TYPE_INVALID,G_TYPE_STRING, &string, G_TYPE_INVALID) ){ 
            if(error->domain == DBUS_GERROR && error->code == DBUS_GERROR_REMOTE_EXCEPTION) 
                g_printerr("Caught remote method exception %s:%s",dbus_g_error_get_name(error),error->message); 
            else 
                g_printerr("Error : %s/n", error->message); 
            g_error_free(error); 
            exit (1); 
        }

        g_print("Message Method return from bus:/n%s/n",string);

        g_free(string); 
        g_object_unref(proxy); 
        return 0; 
    }

    异步的例子

      异步中,程序将不等返回消息,继续执行,等有返回消息的时候,触发一个回调函数 。下面是同样的操作,但是用异步的方式来实现:

    /*  Test for invoke method asynchronously */ 
    #include <stdio.h> 
    #include <stdlib.h> 
    #include <dbus/dbus-glib.h>

    static GMainLoop * main_loop; 

    /* 下面是回调函数,收到method return消息触发函数 */

    static void my_callback_func (DBusGProxy       *proxy, DBusGProxyCall   *call_id,  void  *user_data) 

        GError * error = NULL; 
        gchar * string = NULL; 
        /* 结束一个消息的收发,处理收到的消息,获取返回值或者error信息 */ 
        dbus_g_proxy_end_call (proxy,call_id,&error,G_TYPE_STRING,&string,G_TYPE_INVALID); 
        if(error != NULL){ 
            g_print("Error in method call : %s/n", error->message); 
            g_error_free(error); 
        }else{ 
            g_print("SUCCESS,it is now %s/n",string); 
        } 
        g_main_loop_quit(main_loop); 
    }

    int main( int argc , char ** argv) 

        GError * error = NULL; 
        DBusGConnection * connection; 
        DBusGProxy    * proxy;

        
        g_type_init(); 
        main_loop = g_main_loop_new(NULL,TRUE);

        connection = dbus_g_bus_get (DBUS_BUS_SESSION, & error); 
        if(connection == NULL){ 
            g_printerr ("Failed to open connection to bus : %s/n", 
                    error->message); 
            g_error_free( error); 
            exit( 1 ); 
        }

        /* Create a proxy object for the 'bus driver' named org.freedesktop.DBus */ 
        proxy = dbus_g_proxy_new_for_name (connection, "org.freedesktop.Notifications",  "/",                                 DBUS_INTERFACE_INTROSPECTABLE); 
        /* 异步触发,也可以带上一个超时的时间限制,使用dbus_g_proxy_call_with_timeout 。这里的参数只需带上输入的情况。第四个参数为携带到回调函数的user_data,第五个参数标识释放user_data的函数,例如g_free等*/ 
        dbus_g_proxy_begin_call (proxy,"Introspect",my_callback_func, NULL,NULL, G_TYPE_INVALID); 
        g_main_loop_run(main_loop); 
        return 0; 
    }

      在上面的例子中,使用了GMainLoop的方式,对于线程D-Bus还提供了dbus_g_thread_init 来处理。

  • 相关阅读:
    我开发过程中用到的工具
    我最近写的DataGrid合并/删除相同列通用函数,跟大家分享
    开源项目- Archive Explorer
    SQLite准备出3.0了!
    软件缺陷管理指南 3
    介绍一些.net好站点
    几个著名java开源缓存系统的介绍
    SQL中的Where,Group By,Order By和Having的用法/区别
    Unix/Linux中Cron的用法
    java中判断字符串是否为纯数字
  • 原文地址:https://www.cnblogs.com/cnland/p/3049643.html
Copyright © 2020-2023  润新知