Dbus 使用方式


    轉自http://blog.csdn.net/coroutines/article/details/39313825

        DBus應用的倆種形態及實現                         

 

介紹一下基於DBus設計的應用程序的倆種形態及如何使用GDbus來實現。

基於DBus的應用程序可以是使用DBus Daemon的總線型結構,每個DBus的請求通過DBus Daemon轉發;或者是點對點的星型結構,Client與Server之間是直接的Peer2Peer的連接。這倆種結構各有優缺點:總線型的結構比較清晰,Server需要維護的連接較少,實際上只有一個與DBus Daemon相連的連接,廣播消息可以很容易的發送到各個Client;P2P形式的DBus通信中間因為少了DBus Daemon的中轉,因此性能更好,大約提升30%。

基於GLib提供的GBus實現基於以上倆種形態的DBus應用還是非常簡單的:

1. 准備工作

1.1 提供一個用於代碼生成的XML文件

這份XML數據在GDBus中稱為introspection data,用來描述提供服務的GObject的接口名與參數。用於gdbus-codegen可以使用這份XML文件生成在Client與Server側使用的代碼。對於總線型DBus應用和P2P型DBus應用,這份代碼是通用的。

1.2 編譯生成的代碼

生成的代碼需要分別鏈接到倆個進程中:帶有Skeleton字樣的代碼,運行在Server側;帶有Proxy字樣的代碼,運行在Client側。

 

gdbus-codegen 自動生成的代碼的規則可參考:http://people.freedesktop.org/~david/gio-gdbus-codegen-20110412/gdbus-codegen.html

 

2. 總線型

2.1 Server

2.1.1 提供一個基於Default Context的GLib Mainloop

2.1.2 調用g_bus_own_name在總線上注冊這個Server

2.1.3 提供on_name_acquried的回調函數,在回調函數中,創建一個skeleton對象,並調用g_dbus_interface_skeleton_export輸出到總線上

2.2 Client

2.2.1 提供一個基於Default Context的GLib Mainloop

2.2.2 調用dbus_proxy_new_sync獲取與Server的Skeleton對象相對應的Proxy對象,作為后續DBus方法調用的參數

A.Consider the following D-Bus Introspection XML.

<interface name="net.Corp.MyApp.Frobber">
  <method name="HelloWorld">
    <arg name="greeting" direction="in" type="s"/>
    <arg name="response" direction="out" type="s"/>
  </method>

  <signal name="Notification">
    <arg name="icon_blob" type="ay"/>
    <arg name="height" type="i"/>
    <arg name="messages" type="as"/>
  </signal>

  <property name="Verbose" type="b" access="readwrite"/>
</interface>


B.在server端

static gboolean
on_handle_hello_world (MyAppFrobber           *interface,
                       GDBusMethodInvocation  *invocation,
                       const gchar            *greeting,
                       gpointer                user_data)
{
  if (g_strcmp0 (greeting, "Boo") != 0)
    {
      gchar *response;
      response = g_strdup_printf ("Word! You said `%s'.", greeting);
      my_app_complete_hello_world (interface, invocation, response);
      g_free (response);
    }
  else
    {
      g_dbus_method_invocation_return_error (MY_APP_ERROR,
                 MY_APP_ERROR_NO_WHINING,
                 "Hey, %s, there will be no whining!",
                 g_dbus_method_invocation_get_sender (invocation));
    }
  return TRUE;
}

  [...]

  interface = my_app_frobber_skeleton_new ();
  my_app_frobber_set_verbose (interface, TRUE);

  g_signal_connect (interface,
                    "handle-hello-world",
                    G_CALLBACK (on_handle_hello_world),
                    some_user_data);

  [...]

  error = NULL;
  if (!g_dbus_interface_skeleton_export (G_DBUS_INTERFACE_SKELETON (interface),
                                         connection,
                                         "/path/of/dbus_object",
                                         &error))
    {
      /* handle error */
    }

C.client 端

MyAppFrobber *proxy;
GError *error;

error = NULL;
proxy = my_app_frobber_proxy_new_for_bus_sync (
            G_BUS_TYPE_SESSION,
            G_DBUS_PROXY_FLAGS_NONE,
            "net.Corp.MyApp",              /* bus name */
            "/net/Corp/MyApp/SomeFrobber", /* object */
            NULL,                          /* GCancellable* */
            &error);
/* do stuff with proxy */
g_object_unref (proxy);

 

 

 

3. P2P型

3.1 Server

3.1.1 提供一個基於Default Context的GLib Mainloop

3.1.2 調用g_dbus_server_start啟動一個Server

3.1.3 調用g_signal_connect,關聯callback到Server對象的"new-connection"信號上

3.1.4 提供callback,在callback中創建一個skeleton對象,並調用g_dbus_interface_skeleton_export輸出到這個新建立的連接上

3.2 Client

3.2.1 提供一個基於Default Context的GLib Mainloop

3.2.2 調用g_dbus_connection_new_for_address_sync建立一個到Server的連接

3.2.3 調用dbus_proxy_new_sync創建一個與Server側skeleton對象對應的Proxy對象,作為后續DBus方法調用的參數


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM