GObject/DBus Magic

I am Colin Walters's fanboy. That is all.

I suppose I should elaborate on that. I've just build a shiny new DBus release (from CVS, but for all intents and purposes it is 0.32), and had a quick experiment with the new GLib bindings. In the good old days the GLib bindings provided mainloop integration and not much else, but not any more... I started by creating a simple GObject which has an echo method, this is pretty standard stuff but the echo prototype is:

gboolean echo_echo (Echo *echo, const char in_s, char **out_s, GError **error);

It's nice and simple, out_s is set to a reversed copy of in_s. I then wrote an XML file which describes the object. In the future I believe this will be generated by parsing the C code just as gtk-doc does now, but I can handle writing it manually for now:

<?xml version="1.0"?>
<node name="/com/openedhand/DBus/Tests/Echo">
  <interface name="com.openedhand.DBus.Tests.Echo">
    <annotation name="org.freedesktop.DBus.GLib.CSymbol" value="echo"/>
    <method name="Echo">
      <annotation name="org.freedesktop.DBus.GLib.CSymbol" value="echo_echo"/>
      <arg type="s" name="string" direction="in"/>
      <arg type="s" name="echo_string" direction="out"/>
    </method>
  </interface>
</node>

This file defines the names of the interfaces, objects, and methods in the DBus world, and also how they map to the real GObject. This file is then used to generate two header files: server-side glue for the GObject to the bus, and client-side wrappers around the bus. Ignoring the boring connecting to the bus and error checking, connecting this GObject to the bus is pretty simple:

#include "EchoObjectGlue.h" /* Defines dbus_glib_echo_object_info */

  ...
  obj = g_object_new (ECHO_TYPE, NULL);
  dbus_g_object_class_install_info (G_OBJECT_GET_CLASS (obj), &dbus_glib_echo_object_info);
  dbus_g_connection_register_g_object (connection,
                                       "/com/openedhand/DBus/Tests/Echo",
                                       obj);
    

No more manual argument parsing on the server, which is excellent. Even more exciting is what happens on the client (without error handling but nothing else removed):

#include <dbus/dbus-glib-bindings.h>
#include "EchoObjectBindings.h"
  ...
  DBusGConnection *connection;
  DBusGProxy *proxy;
  char *s_out = NULL;
  
  connection = dbus_g_bus_get (DBUS_BUS_SESSION, NULL);
  proxy = dbus_g_proxy_new_for_name_owner (connection,
                                           "com.openedhand.DBus.Tests.Echo",
                                           "/com/openedhand/DBus/Tests/Echo",
                                           "com.openedhand.DBus.Tests.Echo",
                                           NULL);
  com_openedhand_DBus_Tests_Echo_echo (proxy, "Hello, World", &s_out, NULL); /* Defined in EchoObjectBindings.h */  
  printf("Got '%s'\n", s_out);

The tedious create message-add arguments-send message-wait for reply is gone, and wrapped up inside auto-generated code and introspection frameworks. I believe this is going to make a massive difference to the rate of DBus adoption in GNOME, as until now the prospect of putting complicated structures and methods on the bus wasn't very appealing. Now it's simple and doesn't result in massive code bloat from duplicated code to manipulate the bus messages.

Update: I've put a tarball of the source online. I've also been informed by Colin that Havoc wrote half of the code, so I'm now fanboying both Havoc and Colin.

NP: Babylon Rewound, Thievery Corporation

14:14 Monday, 04 Apr 2005 [#] [computers] (11 comments)

Posted by rjw at Mon Apr 4 17:29:31 2005:
Almost like corba!
Posted by Dmaximus at Wed Oct 12 09:48:45 2005:
Nice description. Do you have any good idea how can use D-Bus in a GTK 1.2 application. The problem is GTK+ 1.2 doesn't use GObject. And one more thing, please I can not find the EchoObjectGlue.h in the tarball :-( Can you make it public? And if it is possible more and more examples would be great :) Yes I know... RTFM
Posted by Ross at Wed Oct 12 09:51:59 2005:
You'd need to write your own GLib 1.2 main loop integration and binding code, this doesn't exist as GTK+ 1.2 is very, very unmaintained.

The Glue.h files is generated at build time, so shouldn't be distributed.
Posted by Philip Van Hoof at Sat Apr 26 17:11:33 2008:
Here's another tutorial about DBus glib-bindings:
http://live.gnome.org/DBusGlibBindings
Posted by manish at Wed Sep 24 08:16:27 2008:
i tried to compile sources attached, but it says that...
undefined reference to `dbus_g_object_class_install_info'.

can u tell me which library has the declaration for this function.

and i included header files in program also
#include <dbus/dbus.h>
#include <dbus/dbus-glib.h>
#include <glib.h>
Posted by Ross at Wed Sep 24 09:22:05 2008:
This example is from over three years ago and has bitrotted.  You now want dbus_g_object_type_install_info().
Posted by manish at Thu Sep 25 11:19:42 2008:
Thanx for reply Ross!!
i could run the code for method “com_openedhand_DBus_Tests_Echo_echo”, which is synchronous one. But, when i try to run the code for asynchronous method “com_openedhand_DBus_Tests_Echo_echo_async” which is already defined in EchoObjectBindings.h. The callback method is not called.

I pass the arguments as
com_openedhand_DBus_Tests_Echo_echo_async (proxy, “Hello”, com_openedhand_DBus_Tests_Echo_echo_async_callback, userdata);

where 
com_openedhand_DBus_Tests_Echo_echo_async_callback : is the name of callback method
and 
userdata : is gpointer.

I get warnings while compling.
EchoObjectClient.c:56: warning: passing argument 3 of âcom_openedhand_DBus_Tests_Echo_echo_asyncâ from incompatible pointer type
EchoObjectClient.c:29: warning: unused variable âs_outâ
EchoObjectClient.c:55: warning: âuserdataâ is used uninitialized in this function

Can you please help me where am I wrong??
Posted by manish at Thu Sep 25 11:40:09 2008:
Thanx for reply Ross!!
i could run the code for method “com_openedhand_DBus_Tests_Echo_echo”, which is synchronous one. But, when i try to run the code for asynchronous method “com_openedhand_DBus_Tests_Echo_echo_async” which is already defined in EchoObjectBindings.h. The callback method is not called.

I pass the arguments as
com_openedhand_DBus_Tests_Echo_echo_async (proxy, “Hello”, com_openedhand_DBus_Tests_Echo_echo_async_callback, userdata);

where 
com_openedhand_DBus_Tests_Echo_echo_async_callback : is the name of callback method
and 
userdata : is gpointer.

I get warnings while compling.
EchoObjectClient.c:56: warning: passing argument 3 of âcom_openedhand_DBus_Tests_Echo_echo_asyncâ from incompatible pointer type
EchoObjectClient.c:29: warning: unused variable âs_outâ
EchoObjectClient.c:55: warning: âuserdataâ is used uninitialized in this function

Can you please help me where am I wrong??
Posted by manish at Thu Sep 25 11:47:03 2008:
Thanx for reply Ross!!
i could run the code for method “com_openedhand_DBus_Tests_Echo_echo”, which is synchronous one. But, when i try to run the code for asynchronous method “com_openedhand_DBus_Tests_Echo_echo_async” which is already defined in EchoObjectBindings.h. The callback method is not called.

I pass the arguments as
com_openedhand_DBus_Tests_Echo_echo_async (proxy, “Hello”, com_openedhand_DBus_Tests_Echo_echo_async_callback, userdata);

where 
com_openedhand_DBus_Tests_Echo_echo_async_callback : is the name of callback method
and 
userdata : is gpointer.

I get warnings while compling.
EchoObjectClient.c:56: warning: passing argument 3 of âcom_openedhand_DBus_Tests_Echo_echo_asyncâ from incompatible pointer type
EchoObjectClient.c:29: warning: unused variable âs_outâ
EchoObjectClient.c:55: warning: âuserdataâ is used uninitialized in this function

Can you please help me where am I wrong??
Posted by manish at Thu Sep 25 13:45:18 2008:
sorry, i dint mean to post the same comment repeatedly. May be it happened, due to some bug in browser. Every time I refreshed the tab, a new comment posted.

Anyways, I cud figure out mistake. :)
Thanks for time.
Posted by manish at Wed Oct 1 06:56:03 2008:
Hi!!
i coud run the code with some modifications and asynchronous method calls are running fine. :)
but, i wanted to implement threads at server side (EchoObject.c). Presently, the main loop calls the designated method whenver it recieves a message. I was wondering is there any way to call that particular method in separeate thread??

Name:


E-mail:


URL:


Add 9 and 9 (required):


Comment: