這是一個建立於 的文章,其中的資訊可能已經有所發展或是發生改變。
D-Bus 核心定義了一套自省機制,這個自省跟物件導向裡的自省有點類似,即可以在運行時查詢對象的相關資訊,包括介面和屬性等。大部分支援 D-Bus 的程式都實現了 org.freedesktop.DBus.Introspectable 這個標準介面,為它們匯出的對象提供自省支援。這個介面只有一個方法 Introspect,它返回對象的XML格式描述。
go.dbus 給出了一個樣本,server.go:
package mainimport ("fmt""github.com/guelfey/go.dbus""github.com/guelfey/go.dbus/introspect""os")const intro = `<node><interface name="com.github.guelfey.Demo"><method name="Foo"><arg direction="out" type="s"/></method></interface>` + introspect.IntrospectDataString + `</node> `type foo stringfunc (f foo) Foo() (string, *dbus.Error) {fmt.Println(f)return string(f), nil}func main() {conn, err := dbus.SessionBus()if err != nil {panic(err)}reply, err := conn.RequestName("com.github.guelfey.Demo",dbus.NameFlagDoNotQueue)if err != nil {panic(err)}if reply != dbus.RequestNameReplyPrimaryOwner {fmt.Fprintln(os.Stderr, "name already taken")os.Exit(1)}f := foo("Bar!")conn.Export(f, "/com/github/guelfey/Demo", "com.github.guelfey.Demo")conn.Export(introspect.Introspectable(intro), "/com/github/guelfey/Demo","org.freedesktop.DBus.Introspectable")fmt.Println("Listening on com.github.guelfey.Demo / /com/github/guelfey/Demo ...")select {}}
運行server.go,使用如下命令對 /com/github/guelfey/Demo 這個對象調用 org.freedesktop.DBus.Introspectable.Introspect:
$ dbus-send --session --print-reply --dest="com.github.guelfey.Demo" /com/github/guelfey/Demo org.freedesktop.DBus.Introspectable.Introspect
就可以得到這個對象的自省資料。
當然,這裡XML字串是寫入程式碼在源檔案中的。手寫XML是一件很無聊的事。這次開源夏令營的目標之一就是自動產生自省資料。具體思路是靜態掃描源檔案,並且支援函數參數名稱和結構體欄位名稱匯出。
go.dbus 對 D-Bus 的核心協議已經有了完整的實現,go-dbus 在此基礎上提供一個更加易用的介面,其底層依然是依賴go.dbus的。這幾天通過研究go.dbus的原始碼,對於D-Bus底層以及如何擴充它都有了更深的瞭解。現在終於感覺這個項目有點眉目清晰的感覺了,接下來就應該編碼來實現具體功能了。