D-Bus


D-Bus三層架構

D-Bus是一個為應用程序間通信的消息總線系統, 用於進程之間的通信。它是個3層架構的IPC 系統,包括:

1、函數庫libdbus ,用於兩個應用程序互相聯系和交互消息。

2、一個基於libdbus構造的消息總線守護進程,可同時與多個應用程序相連,並能把來自一個應用程序的消息路由到0或者多個其他程序。

3、基於特定應用程序框架的封裝庫或捆綁(wrapper libraries or bindings )。例如,libdbus-glib和libdbus-qt,還有綁定在其他語言,例如Python的。大多數開發者都是使用這些封裝庫的API,因為它們簡化了D-Bus編程細節。libdbus被有意設計成為更高層次綁定的底層后端(low-levelbackend )。大部分libdbus的 API僅僅是為了用來實現綁定。

D-Bus進程通信簡單框架


DBUS中消息分為四類:

    1.  Methodcall消息:將觸發一個函數調用 ;

    2.  Methodreturn消息:觸發函數調用返回的結果;

    3.  Error消息:觸發的函數調用返回一個異常 ;

    4.  Signal消息:通知,可以看作為事件消息。


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)                        /*  發送返回消息          */


參考資料:

http://blog.csdn.net/eastmoon502136/article/details/10044993

https://blog.csdn.net/mr_wangning/article/details/60324291

https://www.cnblogs.com/liyiwen/archive/2012/12/02/2798876.html


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM