D-Bus三層架構html
D-Bus是一個爲應用程序間通訊的消息總線系統, 用於進程之間的通訊。它是個3層架構的IPC 系統,包括:編程
一、函數庫libdbus ,用於兩個應用程序互相聯繫和交互消息。後端
二、一個基於libdbus構造的消息總線守護進程,可同時與多個應用程序相連,並能把來自一個應用程序的消息路由到0或者多個其餘程序。架構
三、基於特定應用程序框架的封裝庫或捆綁(wrapper libraries or bindings )。例如,libdbus-glib和libdbus-qt,還有綁定在其餘語言,例如Python的。大多數開發者都是使用這些封裝庫的API,由於它們簡化了D-Bus編程細節。libdbus被有意設計成爲更高層次綁定的底層後端(low-levelbackend )。大部分libdbus的 API僅僅是爲了用來實現綁定。併發
D-Bus進程通訊簡單框架app
DBUS中消息分爲四類:框架
1. Methodcall消息:將觸發一個函數調用 ;異步
2. Methodreturn消息:觸發函數調用返回的結果;函數
3. Error消息:觸發的函數調用返回一個異常 ;ui
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