Migrating from dbus-glib to GDBus
Conceptual differences The central concepts of D-Bus are modelled in a very similar way in dbus-glib and GDBus. Both have a objects representing connections, proxies and method invocations. But there are some important differences: dbus-glib uses libdbus, GDBus doesn't. Instead, it relies on GIO streams as transport layer, and has its own implementation for the the D-Bus connection setup and authentication. Apart from using streams as transport, avoiding libdbus also lets GDBus avoid some thorny multithreading issues. dbus-glib uses the GObject type system for method arguments and return values, including a homegrown container specialization mechanism. GDBus relies uses the #GVariant type system which is explicitly designed to match D-Bus types. The typical way to export an object in dbus-glib involves generating glue code from XML introspection data using dbus-binding-tool. GDBus does not (yet?) use code generation; you are expected to embed the introspection data in your application code.
API comparison dbus-glib APIs and their GDBus counterparts dbus-glibGDBus#DBusGConnection#GDBusConnection#DBusGProxy#GDBusProxy#DBusGMethodInvocation#GDBusMethodInvocationdbus_g_bus_get()g_bus_get_sync(), also see g_bus_get()dbus_g_proxy_new_for_name()g_dbus_proxy_new_sync(), also see g_dbus_proxy_new()dbus_g_proxy_add_signal()not needed, use the generic #GDBusProxy::g-signaldbus_g_proxy_connect_signal()use g_signal_connect() with #GDBusProxy::g-signaldbus_g_connection_register_g_object()g_dbus_connection_register_object()dbus_g_connection_unregister_g_object()g_dbus_connection_unregister_object()dbus_g_object_type_install_info()introspection data is installed while registering an object, see g_dbus_connection_register_object()dbus_g_proxy_begin_call()g_dbus_proxy_call()dbus_g_proxy_end_call()g_dbus_proxy_call_finish()dbus_g_proxy_call()g_dbus_proxy_call_sync()dbus_g_error_domain_register()g_dbus_error_register_error_domain()dbus_g_error_has_name()no direct equivalent, see g_dbus_error_get_remote_error()dbus_g_method_return()g_dbus_method_invocation_return_value()dbus_g_method_return_error()g_dbus_method_invocation_return_error() and variantsdbus_g_method_get_sender()g_dbus_method_invocation_get_sender()
Owning bus names Using dbus-glib, you typically call RequestName manually to own a name, like in the following excerpt: message); g_error_free (error); } else { g_warning ("Failed to acquire %s", NAME_TO_CLAIM); } goto out; } if (result != DBUS_REQUEST_NAME_REPLY_PRIMARY_OWNER) { if (error != NULL) { g_warning ("Failed to acquire %s: %s", NAME_TO_CLAIM, error->message); g_error_free (error); } else { g_warning ("Failed to acquire %s", NAME_TO_CLAIM); } exit (1); } dbus_g_proxy_add_signal (system_bus_proxy, "NameLost", G_TYPE_STRING, G_TYPE_INVALID); dbus_g_proxy_connect_signal (system_bus_proxy, "NameLost", G_CALLBACK (on_name_lost), NULL, NULL); /* further setup ... */ ]]> While you can do things this way with GDBus too, using g_dbus_proxy_call_sync(), it is much nicer to use the high-level API for this: Note that g_bus_own_name() works asynchronously and requires you to enter your mainloop to await the on_name_aquired() callback. Also note that in order to avoid race conditions (e.g. when your service is activated by a method call), you have to export your manager object before acquiring the name. The on_bus_acquired() callback is the right place to do such preparations.
Creating proxies for well-known names dbus-glib lets you create proxy objects for well-known names, like the following example: For a #DBusGProxy constructed like this, method calls will be sent to the current owner of the name, and that owner can change over time. In contrast, #GDBusProxy instances are always bound to a unique name. To get a proxy for a well-known name, you either have to call GetNameOwner yourself and construct a proxy for the unique name of the current name owner, or use the high-level API. The latter option is highly recommended: Like g_bus_own_name(), g_bus_watch_proxy() is asynchronous and you are expected to enter your mainloop to await the on_proxy_appeared() callback. Note that GDBus also does all the setup operations for the proxy asynchronously, and only calls your callback when the proxy is ready for use.
Client-side GObject bindings dbus-glib comes with dbus-binding-tool, which can produce somewhat nice client-side wrappers for a D-Bus interface. GDBus does not have code-generation at this point, but #GDBusProxy is designed to allow the creating of client-side wrappers by subclassing #GDBusProxy. For an example of a #GDBusProxy-derived class that wraps a D-Bus interface in a type-safe way, see . The comparison is as follows: Wrapping the org.freedesktop.Accounts.User D-Bus interface in the AccountUser GObject type D-Bus conceptGObject concept AutomaticLogin property AccountsUser:automatic-login GObject property C getter: accounts_user_get_automatic_login() Watch changes via the notify::automatic-login signal RealName property AccountsUser:real-name GObject property C getter: accounts_user_get_real_name() Watch changes via the notify::real-name signal UserName property AccountsUser:user-name GObject property C getter: accounts_user_get_user_name() Watch changes via the notify::user-name signal Changed signal AccountsUser::changed GObject signal Watch via e.g. g_signal_connect() Frobnicate method Use accounts_user_frobnicate() + accounts_user_frobnicate_finish() or accounts_user_frobnicate_sync() to invoke
GDBusProxy subclass exampleFIXME: MISSING XINCLUDE CONTENT
Exporting objects