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
The Glue.h files is generated at build time, so shouldn't be distributed.
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>
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??
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??
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??
Anyways, I cud figure out mistake. :)
Thanks for time.
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??