1. 程式人生 > >DBUS及常用介面介紹

DBUS及常用介面介紹

     如圖 2‑1所示,程序1(Process1)需先連線到匯流排(dbus_bus_get),其次構造訊息(dbus_message_new_signal),然後傳送訊息(dbus_connection_send)到後臺程序。後臺程序接收訊息,然後根據訊息型別對訊息進行不同處理(bus_dispatch_matches)。

     程序2(Process2)接收訊息前需要連線到匯流排,並告知匯流排自己希望得到的訊息型別(dbus_bus_add_match),然後等待接收訊息(dbus_connection_pop_message)。程序2(Process2)收到匯流排轉發的訊息時會根據訊息型別,做不同的處理(若是訊號型別則不需要傳送返回值給匯流排)。

2.2 連線到匯流排

    程序間通訊前,需要連線到匯流排。呼叫dbus_bus_get函式連線程序到匯流排,建立程序和匯流排之間的連線(DBusConnection)。建立連線後,需要為這個連線註冊名稱,方便後面對這個連線進行操作,呼叫dbus_bus_request_name函式對連線進行註冊名稱。

    建立連線和註冊名稱是在程式開始時執行,程式結束時,呼叫dbus_connection_close函式關閉一個連線。函式介面宣告如程式清單 2‑1所示。

程式清單 2-1 建立、註冊名稱和關閉連線

DBusConnection  *dbus_bus_get  (DBusBusType  type,  DBusError   *error)             /*  建立和匯流排的連線  */

int  dbus_bus_request_name  (DBusConnection   *connection,
                             const char         *name,
                             unsigned int        flags,
                             DBusError        *error)                                   /*  註冊連線名稱      */

void  dbus_connection_close  (DBusConnection  *connection)                           /*  關閉連線          */

2.3 訊號傳送與接收

2.3.1 訊號傳送

    DBUS中訊號是一種廣播的訊息,當發出一個訊號,所有連線到 DBUS 總線上並註冊了接受對應訊號的程序,都會收到該訊號。

    程序發出一個訊號前,需要建立一個 DBusMessage 物件來代表訊號,然後追加上一些需要發出的引數,就可以發向匯流排了。發完之後需要釋放訊息物件。訊號傳送的函式宣告如程式清單 2‑2所示。 程式清單2-2  訊號傳送介面
DBusMessage  *dbus_message_new_signal  (const  char  *path,
                                       const  char  *iface,
                                       const  char  *name)                       /*  建立訊號型別訊息      */

void  dbus_message_iter_init_append  ( DBusMessage     *message,
			               DBusMessageIter  *iter)                /*  加入引數到訊號        */

dbus_bool_t  dbus_connection_send  ( DBusConnection  *connection,
                                     DBusMessage    *message,
                                     dbus_uint32_t    *serial)                       /*  傳送訊號到匯流排        */

void  dbus_message_unref  (DBusMessage *message)                                 /*  釋放訊息              */

2.3.2 訊號接收

    程序接收訊號時,需先告知匯流排程序感興趣的訊息,然後等待接收訊息。訊號接收函式宣告如程式清單 2‑3所示。
程式清單 2-3 訊號接收介面
void  dbus_bus_add_match  ( DBusConnection  *connection,
                            const char        *rule,
                            DBusError       *error)                                 /*  告知匯流排感興趣的訊息   */

DBusMessage  *dbus_connection_pop_message  ( DBusConnection  *connection)         /*  接收訊息               */

dbus_bool_t  dbus_message_is_signal  (DBusMessage  *message,
                                      const char      *iface,
                                      const char     *signal_name)	                  /*  判斷訊息是否為訊號     */

2.4 函式呼叫和提供函式呼叫

2.4.1 函式呼叫

     呼叫一個遠端函式與傳送一個訊號原理類似,需要先建立一個訊息(DBusMessage),然後通過註冊在 DBUS上的名稱指定傳送的物件。然後追加相應的引數,呼叫方法分為兩種,一種是阻塞式的,另一種為非同步呼叫。非同步呼叫的時候會得到一個“DBusMessage *” 型別的返回訊息,從這個返回訊息中可以獲取一些返回的引數。

    函式呼叫的函式宣告如程式清單 2‑4所示。 程式清單 2-4 函式呼叫介面
DBusMessage  *dbus_message_new_method_call  (const char  *destination,
                                             const char  *path,
                                             const char  *iface,
                                             const char  *method)                    /*  建立一個函式呼叫訊息    */

void  dbus_message_iter_init_append  (DBusMessage     *message,
			              DBusMessageIter  *iter)                     /*  為訊息新增引數           */

dbus_bool_t  dbus_connection_send_with_reply  (DBusConnection   *connection,
                                               DBusMessage      *message, 
                                               DBusPendingCall  **pending_return,
                                               int            timeout_milliseconds)       /*  傳送訊息                */

void  dbus_pending_call_block  (DBusPendingCall  *pending)                           /*  阻塞等待返回值           */

DBusMessage  *dbus_pending_call_steal_reply  (DBusPendingCall  *pending)             /*  獲得返回訊息            */
  
dbus_bool_t  dbus_message_iter_init  (DBusMessage     *message,
			              DBusMessageIter  *iter)                     /*  獲取引數                */

2.4.2 接收函式呼叫

    提供遠端函式呼叫,首先需告知匯流排程序感興趣的訊息,其次從匯流排獲取訊息並判定訊息是方法呼叫。然後從訊息中獲取引數進行函式執行,最後建立返回訊息,併發送訊息至匯流排,由匯流排轉發至呼叫的程序。函式宣告如程式清單 2‑5所示。 程式清單 2-5 接收函式呼叫介面
void  dbus_bus_add_match  ( DBusConnection  *connection,
                            const char        *rule,
                            DBusError       *error)                                   /*  請求獲取呼叫訊息       */
 
DBusMessage  *dbus_connection_pop_message  ( DBusConnection  *connection)           /*  從匯流排獲取訊息         */

dbus_bool_t  dbus_message_is_method_call (DBusMessage  *message,
                                          const char     *iface,
                                          const char     *method)                       /*  判定訊息是方法呼叫     */
  
dbus_bool_t  dbus_message_iter_init  (DBusMessage     *message,
			              DBusMessageIter  *iter)                    /*  獲取引數               */

DBusMessage  *dbus_message_new_method_return  (DBusMessage *method_call)            /*  建立返回訊息           */

void  dbus_message_iter_init_append  ( DBusMessage     *message,
			               DBusMessageIter  *iter)                   /*  在訊息中填入引數       */

dbus_bool_t  dbus_connection_send  ( DBusConnection   *connection,
                                     DBusMessage     *message,
                                     dbus_uint32_t     *serial)                        /*  傳送返回訊息          */

3. 小結

    DBUS是一種高效、易用的程序間通訊方式。本文件介紹了DBUS的通訊原理,以訊號收發和方法呼叫為框架,介紹了DBUS中常用的函式介面。

4. 參考資料

     網上看到兩篇寫的很不錯的部落格,可以參考學習。