この記事の概要
DBus を調べる際、利用の仕方、され方については解説がなされているのですが、
開発向けの内容で、日本語でまとまった資料が少なく、イメージをつかむのに苦労しました。
また、実際にコードとして書く際、一部のソースを自動生成させる工程があるのですが、
何を、どこまで手作業で行い、どこから自動生成させるのか
わかりやすくまとまったサイトなどに巡り会えなかったため、一連の作業をまとめようと思います。
DBus の概要や利用方法については Qiita 以外のサイトでは以下にお世話になりました。
- いますぐ実践! Linux システム管理 - D-Bus の存在を感じてみる
- いますぐ実践! Linux システム管理 - D-Bus の存在をもう少し感じてみる
- IBM DeveloperWorks - D-BUSを使用してデスクトップ・アプリケーションを接続 (glib版のDBus)
- 本家 freedesktop.org
DBus 概要の補足
DBus は、Unix系の環境で動作する IPC の一種です。DBus の特徴として、
- 1対1(非同期通信)のみではなく1対多(同期通信)のブロードキャストも可能
- 相手を意識せず、特定のサービス・機能を提供するために利用される傾向
- 相手を意識せず、がキモで相手の開発言語に依らず、特定の機能(関数)を呼び出すこともできる
- 謳い文句としてバイナリ(≠テキスト)通信のため「軽量」
- (なのですが実はそうでもない?本の虫 - Linus Torvalds、「dbusはマジでクソだ」ただ、Linus の言い分だと改善の余地がありそう?)
通信確認用コマンドツールとして dbus-monitor があり、このコマンドで通信内容を傍受することができます。
同様に dbus 送信用のコマンドとして dbus-send がありますが、これらは各所で説明されており、
今回は GUI ツールの qdbusviewer を用いて説明を行いたいと思います。
ubuntu 14.04 だと インストールは以下のコマンドで行えます。
$ sudo apt-get install qttools5-dev-tools
DBus に出てくる用語について
DBus と QtDBus で同じ名称の用語が異なる意味で使われており、ここで一旦整理しておきます。
- Bus (DBus/QtDBus共通)
- システムバス/セッションバス
- 前者はネットワーク設定の変更やデバイス検知など、システム内部の通信に、後者はデスクトップ上のアプリ間通信という住み分け(絶対的なルールではない)
- Path (DBus) == Service (QtDBus)
- 各コネクションは、それぞれ固有の名称で Path == Service 名として DBus-daemon に登録されます。
明示的に登録しなかった場合は、番号での名称(下記画像の:1.493など)が自動的に割り当てられます。 - Object (DBus) == Path (QtDBus)
- 通常、Path == Service 名を明示的に登録した場合、そのドット(.)をスラッシュ(/)に置き換えた名称を Object == Path として習慣的に登録します。
QtDBus における登録は、Path 名がそのまま Object 名として登録されており、Path と Object は同義と解釈して良さそうです。
(ただ、Path という用語は多用されているため、この用語には注意が必要です) - Interface (DBus/QtDBus共通)
- 各コネクション内における機能毎に区分けした名称
- Signal/Method (DBus/QtDBus共通)
- 呼び出し側/呼び出される側の名称ですが、シグナルは非同期通信(ブロードキャスト)で使う送信者側の識別子で、
メソッドは同期通信(1対1通信)の受信者側の関数名になり、対にはなっていません。 - SIGNAL/SLOT (Qt固有)
- DBus とは直接関係ありませんが、Qt 固有の機能に SIGNAL/SLOT があり、SIGNAL が呼ばれると SLOT が呼ばれる、という対の関係を作りコールバックを実現しています。
qdbusviewer 上の各機能名称(DBus)
qdbusviewer 上の各機能名称(QtDBus)
開発の流れ
(タイトルが仰々しいですが)コードの自動生成を用いた開発方法について流れをおって説明していきます。
大まかには以下の流れになります。
※ 以降、QtDBus における用語を用います。
- XML で Interface 名や Signal / Method の関数(引数の数と種別、戻り値も含む)の定義
-
- で作成した XML ファイルを qdbusxml2cpp に食わせ、Interface/Adaptor部のソース&ヘッダーファイルを自動生成
- QtDBus を用いたコーディング
- Adaptor のインスタンスを生成
- Service と Object に登録
- 送信側:同期通信なら送信主を名乗るための登録、非同期通信ならそれ用のインターフェースのインスタンスを生成
- 受信側:同期通信なら受信したい送信主のサービス・オブジェクト・シグナルなどを Qt固有のSIGNAL/SLOT で接続。
非同期通信なら XML で定義した関数と同じものを、SLOT として定義し、受信処理を作成(QObject::connectでの登録は不要)
長くなってしまったので、実作業はその2として投稿します。