言語ゲーム

とあるエンジニアが嘘ばかり書く日記

Twitter: @propella

dbus

最近デスクトップにあるアプリ同士で通信を行うために linux でよく使われるようになった dbus というのを試してみた。ファイルやソケットを使って他のアプリと通信すると、データをいちいち文字列に変換しないといけないのだが、dbus を使うと、単にメソッド呼び出しをする感じで通信が出来て楽なのだそうだ。とりあえず python で動かしてみる。

#!/usr/bin/env python
"Ask what messages dbus can answer."
import dbus

# セッションバス(ユーザごとのバス)と接続する。
bus = dbus.SessionBus()

# bus name が org.freedesktop.DBus で
# object path が /org/freedestop/DBus に接続
object = bus.get_object("org.freedesktop.DBus", "/org/freedestop/DBus")

# オブジェクトの中身を尋ねる
print object.Introspect(dbus_interface="org.freedesktop.DBus.Introspectable")

# 見つけた ListNames を問い合わせる。
print object.ListNames(dbus_interface="org.freedesktop.DBus")

他のアプリのオブジェクトを指定するには、bus name と object path というのを使う。このふたつでオブジェクトを特定して、メッセージを送ると答えが帰る。メッセージを送るには、引数の他に、インタフェースという物が必要だ。あるメッセージは特定のインタフェースに属するという事になっている。

まとめると、あるメッセージを送るには次のように階層的に指定してゆく

  • アドレス(環境変数 DBUS_SESSION_BUS_ADDRESS で指定)
  • bus_name (例 org.freedesktop.DBus)
  • object path (例 /org/freedestop/DBus) (これは ListName で取れないのでどうやって探すのか謎)
  • インタフェース (例 org.freedesktop.DBus.Introspectable)
  • メソッド名 (例 Introspect)

上の例では、まず Introspect() でどんなメソッドがあるのか調べてから、使いかたの簡単そうな、ListNames() を送っている。

もうちょっとましな面白い例として、画面におしらせを表示します。

#!/usr/bin/env python
"Show notifier"
import dbus

bus = dbus.SessionBus()
object = bus.get_object("org.freedesktop.Notifications",
                        "/org/freedesktop/Notifications")
print object.Introspect(dbus_interface="org.freedesktop.DBus.Introspectable")
object.Notify('dbus test', 0, '', 'Hi there','hello!', [], {}, -1,
              dbus_interface="org.freedesktop.Notifications")