D-Bus學習(四):基礎小例子(同步和非同步)

來源:互聯網
上載者:User

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 來處理。

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.