- 進(jìn)程間使用D-Bus通信
D-Bus是一種高級(jí)的進(jìn)程間通信機(jī)制,它由freedesktop.org項(xiàng)目提供汇陆,使用GPL許可證發(fā)行。D-Bus最主要的用途是在Linux桌面環(huán)境為進(jìn)程提供通信,同時(shí)能將Linux桌面環(huán)境和Linux內(nèi)核事件作為消息傳遞到進(jìn)程扛伍。D-Bus的主要概率為總線,注冊(cè)后的進(jìn)程可通過(guò)總線接收或傳遞消息窒百,進(jìn)程也可注冊(cè)后等待內(nèi)核事件響應(yīng)黍判,例如等待網(wǎng)絡(luò)狀態(tài)的轉(zhuǎn)變或者計(jì)算機(jī)發(fā)出關(guān)機(jī)指令。目前篙梢,D-Bus已被大多數(shù)Linux發(fā)行版所采用顷帖,開(kāi)發(fā)者可使用D-Bus實(shí)現(xiàn)各種復(fù)雜的進(jìn)程間通信任務(wù)。
- D-Bus的基本概念
D-Bus是一個(gè)消息總線系統(tǒng)渤滞,其功能已涵蓋進(jìn)程間通信的所有需求贬墩,并具備一些特殊的用途。D-Bus是三層架構(gòu)的進(jìn)程間通信系統(tǒng)妄呕,其中包括:
接口層:接口層由函數(shù)庫(kù)libdbus提供陶舞,進(jìn)程可通過(guò)該庫(kù)使用D-Bus的能力。
總線層:總線層實(shí)際上是由D-Bus總線守護(hù)進(jìn)程提供的绪励。它在Linux系統(tǒng)啟動(dòng)時(shí)運(yùn)行肿孵,負(fù)責(zé)進(jìn)程間的消息路由和傳遞,其中包括Linux內(nèi)核和Linux桌面環(huán)境的消息傳遞疏魏。
包裝層:包裝層一系列基于特定應(yīng)用程序框架的Wrapper庫(kù)停做。
D-Bus具備自身的協(xié)議,協(xié)議基于二進(jìn)制數(shù)據(jù)設(shè)計(jì)大莫,與數(shù)據(jù)結(jié)構(gòu)和編碼方式無(wú)關(guān)蛉腌。該協(xié)議無(wú)需對(duì)數(shù)據(jù)進(jìn)行序列化,保證了信息傳遞的高效性只厘。無(wú)論是libdbus烙丛,還是D-Bus總線守護(hù)進(jìn)程,均不需要太大的系統(tǒng)開(kāi)銷(xiāo)羔味。
總線是D-Bus的進(jìn)程間通信機(jī)制蜀变,一個(gè)系統(tǒng)中通常存在多條總線,這些總線由D-Bus總線守護(hù)進(jìn)程管理介评。最重要的總線為系統(tǒng)總線(System Bus)库北,Linux內(nèi)核引導(dǎo)時(shí),該總線就已被裝入內(nèi)存们陆。只有Linux內(nèi)核寒瓦、Linux桌面環(huán)境和權(quán)限較高的程序才能向該總線寫(xiě)入消息,以此保障系統(tǒng)安全性坪仇,防止有惡意進(jìn)程假冒Linux發(fā)送消息杂腰。
會(huì)話總線(Session Buses)由普通進(jìn)程創(chuàng)建,可同時(shí)存在多條椅文。會(huì)話總線屬于某個(gè)進(jìn)程私有喂很,它用于進(jìn)程間傳遞消息惜颇。
進(jìn)程必須注冊(cè)后才能收到總線中的消息,并且可同時(shí)連接到多條總線中少辣。D-Bus提供了匹配器(Matchers)使進(jìn)程可以有選擇性的接收消息凌摄,另外運(yùn)行進(jìn)程注冊(cè)回調(diào)函數(shù),在收到指定消息時(shí)進(jìn)行處理漓帅。匹配器的功能等同與路由锨亏,用于避免處理無(wú)關(guān)消息造成進(jìn)程的性能下降器予。除此以外,D-Bus機(jī)制的重要概念有以下幾個(gè)乾翔。
對(duì)象:對(duì)象是封裝后的匹配器與回調(diào)函數(shù)施戴,它以對(duì)等(peer-to-peer)協(xié)議使每個(gè)消息都有一個(gè)源地址和一個(gè)目的地址。這些地址又稱(chēng)為對(duì)象路徑,或者稱(chēng)之為總線名稱(chēng)浓瞪。對(duì)象的接口是回調(diào)函數(shù),它以類(lèi)似C++的虛擬函數(shù)實(shí)現(xiàn)乾颁。當(dāng)一個(gè)進(jìn)程注冊(cè)到某個(gè)總線時(shí),都要?jiǎng)?chuàng)建相應(yīng)的消息對(duì)象湾盒。
消息:D-Bus的消息分為信號(hào)(signals)、方法調(diào)用(method calls)罚勾、方法返回(method returns)和錯(cuò)誤(errors)吭狡。信號(hào)是最基本的消息,注冊(cè)的進(jìn)程可簡(jiǎn)單地發(fā)送信號(hào)到總線上划煮,其他進(jìn)程通過(guò)總線讀取消息送丰。方法調(diào)用是通過(guò)總線傳遞參數(shù),執(zhí)行另一個(gè)進(jìn)程接口函數(shù)的機(jī)制弛秋,用于某個(gè)進(jìn)程控制另一個(gè)進(jìn)程器躏。方法返回是注冊(cè)的進(jìn)程在收到相關(guān)信息后俐载,自動(dòng)做出反應(yīng)的機(jī)制,由回調(diào)函數(shù)實(shí)現(xiàn)登失。錯(cuò)誤是信號(hào)的一種遏佣,是注冊(cè)進(jìn)程錯(cuò)誤處理機(jī)制之一。
服務(wù):服務(wù)(Services)是進(jìn)程注冊(cè)的抽象壁畸。進(jìn)程注冊(cè)某個(gè)地址后贼急,即可獲得對(duì)應(yīng)總線的服務(wù)。D-Bus提供了服務(wù)查詢(xún)接口捏萍,進(jìn)程可通過(guò)該接口查詢(xún)某個(gè)服務(wù)是否存在太抓。或者在服務(wù)結(jié)束時(shí)自動(dòng)收到來(lái)自系統(tǒng)的消息令杈。
建立服務(wù)的流程:
建立一個(gè)dbus連接之后 -- dbus_bus_get()走敌,為這個(gè)dbus連接(DbusConnection)起名 -- dbus_bus_request_name(),這個(gè)名字將會(huì)成為我們?cè)诤罄m(xù)進(jìn)行遠(yuǎn)程調(diào)用的時(shí)候的服務(wù)名逗噩,然后我們進(jìn)入監(jiān)聽(tīng)循環(huán) -- dbus_connection_read_write()掉丽。在循環(huán)中,我們從總線上取出消息 -- dbus_connection_pop_message()异雁,并通過(guò)比對(duì)消息中的方法接口名和方法名 -- dbus_message_is_method_call()捶障,如果一致,那么我們跳轉(zhuǎn)到相應(yīng)的處理中去纲刀。在相應(yīng)的處理中项炼,我們會(huì)從消息中取出遠(yuǎn)程調(diào)用的參數(shù)。并且建立起回傳結(jié)果的通路 -- reply_to_method_call()示绊。回傳動(dòng)作本身等同于一次不需要等待結(jié)果的遠(yuǎn)程調(diào)用面褐。
發(fā)送信號(hào)的流程:
建立一個(gè)dbus連接之后湃窍,為這個(gè)dbus連接起名坝咐,建立一個(gè)發(fā)送信號(hào)的通道墨坚,注意盗尸,在建立通道的函數(shù)中泼各,需要我們填寫(xiě)該信號(hào)的接口名和信號(hào)名 -- dbus_message_new_signal()扣蜻。然后我們把信號(hào)對(duì)應(yīng)的相關(guān)參數(shù)壓進(jìn)去 -- dbus_message_iter_init_append(); dbus_message_iter_append_basic()莽使。然后就可以啟動(dòng)發(fā)送了 -- dbus_connection_send(); dbus_connection_flush芳肌。
進(jìn)行一次遠(yuǎn)程調(diào)用的流程:
建立好dbus連接之后亿笤,為這dbus連接命名净薛,申請(qǐng)一個(gè)遠(yuǎn)程調(diào)用通道 -- dbus_message_new_method_call()肃拜,注意,在申請(qǐng)遠(yuǎn)程調(diào)用通道的時(shí)候辱姨,需要填寫(xiě)服務(wù)器名雨涛,本次調(diào)用的接口名替久,和本次調(diào)用名(方法名)蚯根。壓入本次調(diào)用的參數(shù) -- dbus_message_iter_init_append(); dbus_message_iter_append_basic()蒂誉,實(shí)際上是申請(qǐng)了一個(gè)首地址右锨,我們就是把我們真正要傳的參數(shù)绍移,往這個(gè)首地址里面送(送完之后一般都會(huì)判斷是否內(nèi)存越界了)蹂窖。然后就是啟動(dòng)發(fā)送調(diào)用并釋放發(fā)送相關(guān)的消息結(jié)構(gòu) -- dbus_connection_send_with_reply()恼策。這個(gè)啟動(dòng)函數(shù)中帶有一個(gè)句柄涣楷。我們馬上會(huì)阻塞等待這個(gè)句柄給我們帶回總線上回傳的消息。當(dāng)這個(gè)句柄回傳消息之后碳褒,我們從消息結(jié)構(gòu)中分離出參數(shù)沙峻。用dbus提供的函數(shù)提取參數(shù)的類(lèi)型和參數(shù) -- dbus_message_iter_init(); dbus_message_iter_next(); dbus_message_iter_get_arg_type(); dbus_message_iter_get_basic()摔寨。也就達(dá)成了我們進(jìn)行本次遠(yuǎn)程調(diào)用的目的了是复。
信號(hào)接收流程:
建立一個(gè)dbus連接之后淑廊,為這個(gè)dbus連接起名季惩,為我們將要進(jìn)行的消息循環(huán)添加匹配條件(就是通過(guò)信號(hào)名和信號(hào)接口名來(lái)進(jìn)行匹配控制的) -- dbus_bus_add_match()关摇。我們進(jìn)入等待循環(huán)后输虱,只需要對(duì)信號(hào)名宪睹,信號(hào)接口名進(jìn)行判斷就可以分別處理各種信號(hào)了亭病。在各個(gè)處理分支上。我們可以分離出消息中的參數(shù)整袁。對(duì)參數(shù)類(lèi)型進(jìn)行判斷和其他的處理坐昙。
dbus_connection_read_write()
As long as the connection is open, this function will block until it can read or write, then read or write, then return #TRUE.
If the connection is closed, the function returns #FALSE.
dbus_connection_pop_message()
Returns the first-received message from the incoming message queue, removing it from the queue. The caller owns a reference to the returned message. If the queue is empty, returns #NULL.
dbus_connection_send()
Adds a message to the outgoing message queue. Does not block to write the message to the network; that happens asynchronously. To force the message to be written, call dbus_connection_flush(). Because this only queues the message, the only reason it can
fail is lack of memory. Even if the connection is disconnected, no error will be returned.
@param connection the connection.
@param message the message to write.
@param serial return location for message serial, or #NULL if you don't care
@returns #TRUE on success.
dbus_connection_send_with_reply()
Queues a message to send, as with dbus_connection_send(), but also returns a #DBusPendingCall used to receive a reply to the message. If no reply is received in the given timeout_milliseconds, this function expires the pending reply and generates a synthetic error reply (generated in-process, not by the remote application) indicating that a timeout occurred.
A #DBusPendingCall will see a reply message before any filters or registered object path handlers. See dbus_connection_dispatch() for details on when handlers are run.
A #DBusPendingCall will always see exactly one reply message, unless it's cancelled with dbus_pending_call_cancel().
If #NULL is passed for the pending_return, the #DBusPendingCall will still be generated internally, and used to track the message reply timeout. This means a timeout error will occur if no reply arrives, unlike with dbus_connection_send().
If -1 is passed for the timeout, a sane default timeout is used. -1 is typically the best value for the timeout for this reason, unless you want a very short or very long timeout. There is no way to avoid a timeout entirely, other than passing INT_MAX for the
timeout to mean "very long timeout." libdbus clamps an INT_MAX timeout down to a few hours timeout though.
@warning if the connection is disconnected, the #DBusPendingCall will be set to #NULL, so be careful with this.
@param connection the connection
@param message the message to send
@param pending_return return location for a #DBusPendingCall object, or #NULL if connection is disconnected
@param timeout_milliseconds timeout in milliseconds or -1 for default
@returns #FALSE if no memory, #TRUE otherwise.
dbus_message_is_signal()
Checks whether the message is a signal with the given interface and member fields. If the message is not #DBUS_MESSAGE_TYPE_SIGNAL, or has a different interface or member field, returns #FALSE.
dbus_message_iter_init()
Initializes a #DBusMessageIter for reading the arguments of the message passed in.
dbus_message_iter_next()
Moves the iterator to the next field, if any. If there's no next field, returns #FALSE. If the iterator moves forward, returns #TRUE.
dbus_message_iter_get_arg_type()
Returns the argument type of the argument that the message iterator points to. If the iterator is at the end of the message, returns #DBUS_TYPE_INVALID.
dbus_message_iter_get_basic()
Reads a basic-typed value from the message iterator. Basic types are the non-containers such as integer and string.
dbus_message_new_signal()
Constructs a new message representing a signal emission. Returns #NULL if memory can't be allocated for the message. A signal is identified by its originating object path, interface, and the name of the signal.
Path, interface, and signal name must all be valid (the D-Bus specification defines the syntax of these fields).
@param path the path to the object emitting the signal
@param interface the interface the signal is emitted from
@param name name of the signal
@returns a new DBusMessage, free with dbus_message_unref()
dbus_message_iter_init_append()
Initializes a #DBusMessageIter for appending arguments to the end of a message.
@param message the message
@param iter pointer to an iterator to initialize
dbus_message_iter_append_basic()
Appends a basic-typed value to the message. The basic types are the non-container types such as integer and string.
@param iter the append iterator
@param type the type of the value
@param value the address of the value
@returns #FALSE if not enough memory
dbus_message_new_method_call()
Constructs a new message to invoke a method on a remote object. Returns #NULL if memory can't be allocated for the message. The destination may be #NULL in which case no destination is set; this is appropriate when using D-Bus in a peer-to-peer context (no message bus). The interface may be #NULL, which means that if multiple methods with the given name exist it is undefined which one will be invoked.
The path and method names may not be #NULL.
Destination, path, interface, and method name can't contain any invalid characters (see the D-Bus specification).
@param destination name that the message should be sent to or #NULL
@param path object path the message should be sent to
@param interface interface to invoke method on, or #NULL
@param method method to invoke
@returns a new DBusMessage, free with dbus_message_unref()
dbus_bus_get()
Connects to a bus daemon and registers the client with it. If a connection to the bus already exists, then that connection is returned. The caller of this function owns a reference to the bus.
@param type bus type
@param error address where an error can be returned.
@returns a #DBusConnection with new ref
dbus_bus_request_name()
Asks the bus to assign the given name to this connection by invoking the RequestName method on the bus.
First you should know that for each bus name, the bus stores a queue of connections that would like to own it. Only one owns it at a time - called the primary owner. If the primary owner releases the name or disconnects, then the next owner in the queue atomically takes over.
So for example if you have an application org.freedesktop.TextEditor and multiple instances of it can be run, you can have all of them sitting in the queue. The first one to start up will receive messages sent to org.freedesktop.TextEditor, but if that one exits another will become the primary owner and receive messages.
The queue means you don't need to manually watch for the current owner to disappear and then request the name again.
@param connection the connection
@param name the name to request
@param flags flags
@param error location to store the error
@returns a result code, -1 if error is set
給DBusConnection起名字(命名) -- 兩個(gè)相互通信的連接(connection)不能同名
命名規(guī)則: xxx.xxx (zeng.xiaolong)
dbus_bus_add_match()
Adds a match rule to match messages going through the message bus. The "rule" argument is the string form of a match rule.
@param connection connection to the message bus
@param rule textual form of match rule
@param error location to store any errors
dbus_pending_call_block()
Block until the pending call is completed. The blocking is as with dbus_connection_send_with_reply_and_block(); it does not enter the main loop or process other messages, it simply waits for the reply in question.
If the pending call is already completed, this function returns immediately.
@todo when you start blocking, the timeout is reset, but it should really only use time remaining since the pending call was created. This requires storing timestamps instead of intervals in the timeout
@param pending the pending call
dbus_pending_call_steal_reply()
Gets the reply, or returns #NULL if none has been received yet. Ownership of the reply message passes to the caller. This function can only be called once per pending call, since the reply message is tranferred to the caller.
@param pending the pending call
@returns the reply message or #NULL.
安裝D-Bus可在其官方網(wǎng)站下載源碼編譯宣渗,地址為http://dbus.freedesktop.org痕囱”┙常或者在終端上輸入下列指令:
yum install dbus dbus-devel dbus-doc
安裝后帮掉,頭文件位于"/usr/include/dbus-<版本號(hào)>/dbus"目錄中蟆炊,編譯使用D-Bus的程序時(shí)需加入編譯指令"pkg-config --cflags --libs dbus-1
"污秆。
- D-Bus的用例
在使用GNOME桌面環(huán)境的Linux系統(tǒng)中良拼,通常用GLib庫(kù)提供的函數(shù)來(lái)管理總線庸推。在測(cè)試下列用例前,首先需要安裝GTK+開(kāi)發(fā)包(見(jiàn)22.3節(jié))并配置編譯環(huán)境掖蛤。該用例一共包含兩個(gè)程序文件蚓庭,每個(gè)程序文件需單獨(dú)編譯成為可執(zhí)行文件。
1.消息發(fā)送程序
"dbus-ding-send.c"程序每秒通過(guò)會(huì)話總線發(fā)送一個(gè)參數(shù)為字符串Ding!的信號(hào)港柜。該程序的源代碼如下:
include <glib.h> // 包含glib庫(kù)
include <dbus/dbus-glib.h> // 包含
glib庫(kù)中D-Bus管理庫(kù)
include <stdio.h>
static gboolean send_ding(DBusConnection *bus);// 定義發(fā)送消息函數(shù)的原型
int main ()
{
GMainLoop *loop; // 定義一個(gè)事件循環(huán)對(duì)象的指針
DBusConnection *bus; // 定義總線連接對(duì)象的指針
DBusError error; // 定義D-Bus錯(cuò)誤消息對(duì)象
loop = g_main_loop_new(NULL, FALSE); // 創(chuàng)建新事件循環(huán)對(duì)象
dbus_error_init (&error); // 將錯(cuò)誤消息對(duì)象連接到D-Bus
// 錯(cuò)誤消息對(duì)象
bus = dbus_bus_get(DBUS_BUS_SESSION, &error);// 連接到總線
if (!bus) { // 判斷是否連接錯(cuò)誤
g_warning("連接到D-Bus失敗: %s", error.message);
// 使用GLib輸出錯(cuò)誤警告信息
dbus_error_free(&error); // 清除錯(cuò)誤消息
return 1;
}
dbus_connection_setup_with_g_main(bus, NULL);
// 將總線設(shè)為接收GLib事件循環(huán)
g_timeout_add(1000, (GSourceFunc)send_ding, bus);
// 每隔1000ms調(diào)用一次send_ding()函數(shù)
// 將總線指針作為參數(shù)
g_main_loop_run(loop); // 啟動(dòng)事件循環(huán)
return 0;
}
static gboolean send_ding(DBusConnection *bus) // 定義發(fā)
送消息函數(shù)的細(xì)節(jié)
{
DBusMessage *message; // 創(chuàng)建消息對(duì)象指針
message = dbus_message_new_signal("/com/burtonini/dbus/ding",
"com.burtonini.dbus.Signal",
"ding"); // 創(chuàng)建消息對(duì)象并標(biāo)識(shí)路徑
dbus_message_append_args(message,
DBUS_TYPE_STRING, "ding!",
DBUS_TYPE_INVALID); //將字符串Ding!定義為消息
dbus_connection_send(bus, message, NULL); // 發(fā)送該消息
dbus_message_unref(message); // 釋放消息對(duì)象
g_print("ding!\n"); // 該函數(shù)等同與標(biāo)準(zhǔn)輸入輸出
return TRUE;
}
main()函數(shù)創(chuàng)建一個(gè)GLib事件循環(huán)畔柔,獲得會(huì)話總線的一個(gè)連接靶擦,并將D-Bus事件處理集成到GLib事件循環(huán)之中玄捕。然后它創(chuàng)建了一個(gè)名為send_ding()函數(shù)作為間隔為一秒的計(jì)時(shí)器馅闽,并啟動(dòng)事件循環(huán)馍迄。send_ding()函數(shù)構(gòu)造一個(gè)來(lái)自于對(duì)象路徑"/com/burtonini/dbus/ding"和接口"com.burtonini.dbus.Signal"的新的Ding信號(hào)捞蛋。然后,字符串Ding!作為參數(shù)添加到信號(hào)中并通過(guò)總線發(fā)送柬姚。在標(biāo)準(zhǔn)輸出中會(huì)打印一條消息以讓用戶(hù)知道發(fā)送了一個(gè)信號(hào)拟杉。
2.消息接收程序
dbus-ding-listen.c程序通過(guò)會(huì)話總線接收dbus-ding-send.c程序發(fā)送到消息。該程序的源代碼如下:
include <glib.h> // 包含glib庫(kù)
include <dbus/dbus-glib.h> // 包含glib庫(kù)中D-Bus管理庫(kù)
static DBusHandlerResult signal_filter // 定義接收消息函數(shù)的原型
(DBusConnection *connection, DBusMessage *message, void *user_data);
int main()
{
GMainLoop *loop; // 定義一個(gè)事件循環(huán)對(duì)象的指針
DBusConnection *bus; // 定義總線連接對(duì)象的指針
DBusError error; // 定義D-Bus錯(cuò)誤消息對(duì)象
loop = g_main_loop_new(NULL, FALSE); // 創(chuàng)建新事件循環(huán)對(duì)象
dbus_error_init(&error); // 將錯(cuò)誤消息對(duì)象連接到D-Bus
// 錯(cuò)誤消息對(duì)象
bus = dbus_bus_get(DBUS_BUS_SESSION, &error); // 連接到總線
if (!bus) { // 判斷是否連接錯(cuò)誤
g_warning("連接到D-Bus失敗: %s", error.message);
// 使用GLib輸出錯(cuò)誤警告信息
dbus_error_free(&error); // 清除錯(cuò)誤消息
return 1;
}
dbus_connection_setup_with_g_main(bus, NULL);
// 將總線設(shè)為接收GLib事件循環(huán)
dbus_bus_add_match(bus, "type='signal',interface
='com.burtonini.dbus.Signal'"); // 定義匹配器
dbus_connection_add_filter(bus, signal_filter, loop, NULL);
// 調(diào)用函數(shù)接收消息
g_main_loop_run(loop); // 啟動(dòng)事件循環(huán)
return 0;
}
static DBusHandlerResult // 定義接收消息函數(shù)的細(xì)節(jié)
signal_filter (DBusConnection *connection,
DBusMessage *message, void *user_data)
{
GMainLoop *loop = user_data; // 定義事件循環(huán)對(duì)象的指針量承,并與主函數(shù)中的同步
if (dbus_message_is_signal // 接收連接成功消息搬设,判斷是否連接失敗
(message, DBUS_INTERFACE_ORG_FREEDESKTOP_LOCAL,
"Disconnected")) {
g_main_loop_quit (loop); // 退出主循環(huán)
return DBUS_HANDLER_RESULT_HANDLED;
}
if (dbus_message_is_signal(message, "com.burtonini.dbus.Signal",
"Ping")) {
// 指定消息對(duì)象路徑,判斷是否成功
DBusError error; // 定義錯(cuò)誤對(duì)象
char *s;
dbus_error_init(&error); // 將錯(cuò)誤消息對(duì)象連接到D-Bus錯(cuò)誤
// 消息對(duì)象
if (dbus_message_get_args // 接收消息撕捍,并判斷是否有錯(cuò)誤
(message, &error, DBUS_TYPE_STRING, &s,
DBUS_TYPE_INVALID)) {
g_print("接收到的消息是: %s\n", s); // 輸出接收到的消息
dbus_free (s); // 清除該消息
}
else { // 有錯(cuò)誤時(shí)執(zhí)行下列語(yǔ)句
g_print("消息已收到,但有錯(cuò)誤提示: %s\n", error.message);
dbus_error_free (&error);
}
return DBUS_HANDLER_RESULT_HANDLED;
}
return DBUS_HANDLER_RESULT_NOT_YET_HANDLED;
}
該程序偵聽(tīng)dbus-ping-send.c程序正在發(fā)出的信號(hào)。main()函數(shù)和前面一樣啟動(dòng)贴硫,創(chuàng)建一個(gè)到總線的連接。然后它聲明愿意在使用com.burtonini.dbus.Signal接口的信號(hào)被發(fā)送時(shí)得到通知,將signal_filter()函數(shù)設(shè)置為通知函數(shù),然后進(jìn)入事件循環(huán)。當(dāng)滿(mǎn)足匹配的消息被發(fā)送時(shí),signal_func()函數(shù)會(huì)被調(diào)用昔搂。
如果需要確定在接收消息時(shí)如何處理逛裤,可通過(guò)檢測(cè)消息頭實(shí)現(xiàn)蝙砌。若收到的消息為總線斷開(kāi)信號(hào)祠饺,則主事件循環(huán)將被終止,因?yàn)楸O(jiān)聽(tīng)的總線已經(jīng)不存在了换途。若收到其他的消息誓禁,首先將收到的消息與期待的消息進(jìn)行比較俗慈,兩者相同則輸出其中參數(shù)观蓄,并退出程序麸拄。兩者不相同則告知總線并沒(méi)有處理該消息五慈,這樣消息會(huì)繼續(xù)保留在總線中供別的程序處理争拐。
原文網(wǎng)址: http://www.cnblogs.com/wzh206/archive/2010/05/13/1734901.html
[DBUS 資源]
(http://www.cnblogs.com/wzh206/archive/2010/05/13/1734910.html)
(1)Connect desktop apps using D-BUS:http://www-128.ibm.com/developerworks/linux/library/l-dbus.html?ca=dgr-lnxw95D-BUS.
一個(gè)外國(guó)牛人寫(xiě)的有關(guān)DBUS的簡(jiǎn)介,附有簡(jiǎn)單的例程,但例程需要稍做修改才能編譯通過(guò),修改后的函數(shù)signal_filter和send_ping如下:
(2)http://hi.baidu.com/zengzhaonong/blog/item/670b98d6e63ae42c07088bae.html
這里的例子給出了DBus上幾種消息的發(fā)送、接收程序框架,例子很容易看明白赌厅,一般在此框架上做些修改即可得到自己需要的代碼。
(3)http://blog.csdn.net/fmddlmyy/archive/2008/12/23/3585730.aspx
這個(gè)博客的博主正準(zhǔn)備詳細(xì)深入的介紹DBus的方方面面采驻,博主剛開(kāi)始討論DBus不久,博客還在持續(xù)更新中烛卧,估計(jì)博主已經(jīng)在DBus上已經(jīng)有深厚的功底,請(qǐng)?zhí)貏e關(guān)注 :》
(4)http://blog.chinaunix.net/u1/58649/showart_462468.html
這里是一個(gè)比較全的例子,600多行的程序涉及了DBus的方方面面,有極高的參考價(jià)值。
(5)http://blog.csdn.net/cuijpus
這個(gè)博客的博主是做手機(jī)開(kāi)發(fā)的,在DBus上也有很深的功底倒源,一些例程很值得學(xué)習(xí)。
(6)freedesktop.org - Software-dbus.url
DBus Home,這個(gè)是最重要也是最有價(jià)值的參考資料倦蚪,DBus的相關(guān)源代碼和文檔都在這里捶枢,另外網(wǎng)站還給出了一些使用DBus的開(kāi)放源代碼項(xiàng)目列表烂叔,如果你編寫(xiě)DBus某一方面的代碼時(shí)遇到困惑谨胞,網(wǎng)上又找不到可供參考的例子,到這些open source中去serch相關(guān)源代碼或許是一個(gè)很有效的方法蒜鸡。
原文地址 http://cid-121d380d29ebce85.spaces.live.com/Blog/cns!121D380D29EBCE85!422.entry?fl=cat