diff options
author | Ross Burton <ross@openedhand.com> | 2005-12-19 18:11:05 +0000 |
---|---|---|
committer | Ross Burton <ross@openedhand.com> | 2005-12-19 18:11:05 +0000 |
commit | f72c693f48d8be621e912366457699f787089400 (patch) | |
tree | c987b53c765ecb1a3dc0407289c8bdf0e5170cf5 | |
parent | 1ae3003571fdf3061e7fe2a0e66945e2c87089fe (diff) | |
download | dbus-f72c693f48d8be621e912366457699f787089400.tar.gz |
Add documentation on glib client bindings and annotations
-rw-r--r-- | ChangeLog | 5 | ||||
-rw-r--r-- | doc/dbus-tutorial.xml | 264 |
2 files changed, 245 insertions, 24 deletions
@@ -1,3 +1,8 @@ +2005-12-19 Ross Burton <ross@openedhand.com> + + * doc/dbus-tutorial.xml: + Document the Glib client-side bindings, and list all possible annotations. + 2005-12-19 John (J5) Palmieri <johnp@redhat.com> * dbus/bus.c (dbus_bus_release_name): Add documentation diff --git a/doc/dbus-tutorial.xml b/doc/dbus-tutorial.xml index a5b210b6..78e8489c 100644 --- a/doc/dbus-tutorial.xml +++ b/doc/dbus-tutorial.xml @@ -15,9 +15,7 @@ <surname>Pennington</surname> <affiliation> <orgname>Red Hat, Inc.</orgname> - <address> - <email>hp@pobox.com</email> - </address> + <address><email>hp@pobox.com</email></address> </affiliation> </author> <author> @@ -29,9 +27,7 @@ <surname>Palmieri</surname> <affiliation> <orgname>Red Hat, Inc.</orgname> - <address> - <email>johnp@redhat.com</email> - </address> + <address><email>johnp@redhat.com</email></address> </affiliation> </author> <author> @@ -39,9 +35,7 @@ <surname>Walters</surname> <affiliation> <orgname>Red Hat, Inc.</orgname> - <address> - <email>walters@redhat.com</email> - </address> + <address><email>walters@redhat.com</email></address> </affiliation> </author> </authorgroup> @@ -470,7 +464,7 @@ <para> The GLib binding is defined in the header file - <dbus/dbus-glib.h>. + <literal><dbus/dbus-glib.h></literal>. </para> <sect2 id="glib-typemappings"> @@ -511,22 +505,22 @@ <entry><literal>INT16</literal></entry> <entry><literal>G_TYPE_INT</literal></entry> <entry></entry> - <entry>Will be changed to a G_TYPE_INT16 once GLib has it</entry> + <entry>Will be changed to a <literal>G_TYPE_INT16</literal> once GLib has it</entry> </row><row> <entry><literal>UINT16</literal></entry> <entry><literal>G_TYPE_UINT</literal></entry> <entry></entry> - <entry>Will be changed to a G_TYPE_UINT16 once GLib has it</entry> + <entry>Will be changed to a <literal>G_TYPE_UINT16</literal> once GLib has it</entry> </row><row> <entry><literal>INT32</literal></entry> <entry><literal>G_TYPE_INT</literal></entry> <entry></entry> - <entry>Will be changed to a G_TYPE_INT32 once GLib has it</entry> + <entry>Will be changed to a <literal>G_TYPE_INT32</literal> once GLib has it</entry> </row><row> <entry><literal>UINT32</literal></entry> <entry><literal>G_TYPE_UINT</literal></entry> <entry></entry> - <entry>Will be changed to a G_TYPE_UINT32 once GLib has it</entry> + <entry>Will be changed to a <literal>G_TYPE_UINT32</literal> once GLib has it</entry> </row><row> <entry><literal>INT64</literal></entry> <entry><literal>G_TYPE_GINT64</literal></entry> @@ -545,12 +539,12 @@ </row><row> <entry><literal>STRING</literal></entry> <entry><literal>G_TYPE_STRING</literal></entry> - <entry>g_free</entry> + <entry><literal>g_free</literal></entry> <entry></entry> </row><row> <entry><literal>OBJECT_PATH</literal></entry> <entry><literal>DBUS_TYPE_G_PROXY</literal></entry> - <entry>g_object_unref</entry> + <entry><literal>g_object_unref</literal></entry> <entry>The returned proxy does not have an interface set; use <literal>dbus_g_proxy_set_interface</literal> to invoke methods</entry> </row> </tbody> @@ -581,7 +575,7 @@ </para> <para> First, D-BUS type signatures which have an "obvious" - corresponding builtin GLib type are mapped using that type: + corresponding built-in GLib type are mapped using that type: <informaltable> <tgroup cols="6"> <thead> @@ -600,14 +594,14 @@ <entry>Array of strings</entry> <entry><literal>G_TYPE_STRV</literal></entry> <entry><literal>char **</literal></entry> - <entry>g_strfreev</entry> + <entry><literal>g_strfreev</literal></entry> <entry></entry> </row><row> <entry><literal>v</literal></entry> <entry>Generic value container</entry> <entry><literal>G_TYPE_VALUE</literal></entry> <entry><literal>GValue *</literal></entry> - <entry>g_value_unset</entry> + <entry><literal>g_value_unset</literal></entry> <entry>The calling conventions for values expect that method callers have allocated return values; see below.</entry> </row> </tbody> @@ -836,7 +830,7 @@ main (int argc, char **argv) <para> You have a number of choices for method invocation. First, as used above, <literal>dbus_g_proxy_call</literal> sends a - method call to the remote object, and blocks until reply is + method call to the remote object, and blocks until a reply is recieved. The outgoing arguments are specified in the varargs array, terminated with <literal>G_TYPE_INVALID</literal>. Next, pointers to return values are specified, followed again @@ -1073,6 +1067,83 @@ main (int argc, char **argv) </para> </sect3> </sect2> + + <sect2 id="glib-generated-bindings"> + <title>Generated Bindings</title> + <para> + By using the Introspection XML files, convenient client-side bindings + can be automatically created to ease the use of a remote DBus object. + </para> + <para> + Here is a sample XML file which describes an object that exposes + one method, named <literal>ManyArgs</literal>. + <programlisting> +<?xml version="1.0" encoding="UTF-8" ?> +<node name="/com/example/MyObject"> + <interface name="com.example.MyObject"> + <method name="ManyArgs"> + <arg type="u" name="x" direction="in" /> + <arg type="s" name="str" direction="in" /> + <arg type="d" name="trouble" direction="in" /> + <arg type="d" name="d_ret" direction="out" /> + <arg type="s" name="str_ret" direction="out" /> + </method> + </interface> +</node> +</programlisting> + </para> + <para> + Run <literal>dbus-binding-tool --mode=glib-client + <replaceable>FILENAME</replaceable> > + <replaceable>HEADER_NAME</replaceable></literal> to generate the header + file. For example: <command>dbus-binding-tool --mode=glib-client + my-object.xml > my-object-bindings.h</command>. This will generate + inline functions with the following prototypes: + <programlisting> +/* This is a blocking call */ +gboolean +com_example_MyObject_many_args (DBusGProxy *proxy, const guint IN_x, + const char * IN_str, const gdouble IN_trouble, + gdouble* OUT_d_ret, char ** OUT_str_ret, + GError **error); + +/* This is a non-blocking call */ +DBusGProxyCall* +com_example_MyObject_many_args_async (DBusGProxy *proxy, const guint IN_x, + const char * IN_str, const gdouble IN_trouble, + com_example_MyObject_many_args_reply callback, + gpointer userdata); + +/* This is the typedef for the non-blocking callback */ +typedef void +(*com_example_MyObject_many_args_reply) +(DBusGProxy *proxy, gdouble OUT_d_ret, char * OUT_str_ret, + GError *error, gpointer userdata); +</programlisting> + The first argument in all functions is a <literal>DBusGProxy + *</literal>, which you should create with the usual + <literal>dbus_g_proxy_new_*</literal> functions. Following that are the + "in" arguments, and then either the "out" arguments and a + <literal>GError *</literal> for the synchronous (blocking) function, or + callback and user data arguments for the asynchronous (non-blocking) + function. The callback in the asynchronous function passes the + <literal>DBusGProxy *</literal>, the returned "out" arguments, an + <literal>GError *</literal> which is set if there was an error otherwise + <literal>NULL</literal>, and the user data. + </para> + <para> + As with the server-side bindings support (see <xref + linkend="glib-server"/>), the exact behaviour of the client-side + bindings can be manipulated using "annotations". Currently the only + annotation used by the client bindings is + <literal>org.freedesktop.DBus.GLib.NoReply</literal>, which sets the + flag indicating that the client isn't expecting a reply to the method + call, so a reply shouldn't be sent. This is often used to speed up + rapid method calls where there are no "out" arguments, and not knowing + if the method succeeded is an acceptable compromise to half the traffic + on the bus. + </para> + </sect2> </sect1> <sect1 id="glib-server"> @@ -1118,13 +1189,13 @@ main (int argc, char **argv) </para> <para> Once you have written this XML, run <literal>dbus-binding-tool --mode=glib-server <replaceable>FILENAME</replaceable> > <replaceable>HEADER_NAME</replaceable>.</literal> to - generate a header file. For example: <command>dbus-binding-tool --mode=glib-server my-objet.xml > my-object-glue.h</command>. + generate a header file. For example: <command>dbus-binding-tool --mode=glib-server my-object.xml > my-object-glue.h</command>. </para> <para> Next, include the generated header in your program, and invoke - <literal>dbus_g_object_class_install_info</literal>, passing the - object class and "object info" included in the header. For - example: + <literal>dbus_g_object_class_install_info</literal> in the class + initializer, passing the object class and "object info" included in the + header. For example: <programlisting> dbus_g_object_type_install_info (COM_FOO_TYPE_MY_OBJECT, &com_foo_my_object_info); </programlisting> @@ -1177,6 +1248,151 @@ main (int argc, char **argv) obj); </programlisting> </para> + + <sect2 id="glib-annotations"> + <title>Server-side Annotations</title> + <para> + There are several annotations that are used when generating the + server-side bindings. The most common annotation is + <literal>org.freedesktop.DBus.GLib.CSymbol</literal> but there are other + annotations which are often useful. + <variablelist> + <varlistentry> + <term><literal>org.freedesktop.DBus.GLib.CSymbol</literal></term> + <listitem> + <para> + This annotation is used to specify the C symbol names for + the various types (interface, method, etc), if it differs from the + name DBus generates. + </para> + </listitem> + </varlistentry> + <varlistentry> + <term><literal>org.freedesktop.DBus.GLib.Async</literal></term> + <listitem> + <para> + This annotation marks the method implementation as an + asynchronous function, which doesn't return a response straight + away but will send the response at some later point to complete + the call. This is used to implement non-blocking services where + method calls can take time. + </para> + <para> + When a method is asynchronous, the function prototype is + different. It is required that the function conform to the + following rules: + <itemizedlist> + <listitem> + <para> + The function must return a value of type <literal>gboolean</literal>; + <literal>TRUE</literal> on success, and <literal>FALSE</literal> + otherwise. TODO: the return value is currently ignored. + </para> + </listitem> + <listitem> + <para> + The first parameter is a pointer to an instance of the object. + </para> + </listitem> + <listitem> + <para> + Following the object instance pointer are the method + input values. + </para> + </listitem> + <listitem> + <para> + The final parameter must be a + <literal>DBusGMethodInvocation *</literal>. This is used + when sending the response message back to the client, by + calling <literal>dbus_g_method_return</literal> or + <literal>dbus_g_method_return_error</literal>. + </para> + </listitem> + </itemizedlist> + </para> + </listitem> + </varlistentry> + <varlistentry> + <term><literal>org.freedesktop.DBus.GLib.Const</literal></term> + <listitem> + <para>This attribute can only be applied to "out" + <literal><arg></literal> nodes, and specifies that the + parameter isn't being copied when returned. For example, this + turns a 's' argument from a <literal>char **</literal> to a + <literal>const char **</literal>, and results in the argument not + being freed by DBus after the message is sent. + </para> + </listitem> + </varlistentry> + <varlistentry> + <term><literal>org.freedesktop.DBus.GLib.ReturnVal</literal></term> + <listitem> + <para> + This attribute can only be applied to "out" + <literal><arg></literal> nodes, and alters the expected + function signature. It currently can be set to two values: + <literal>""</literal> or <literal>"error"</literal>. The + argument marked with this attribute is not returned via a + pointer argument, but by the function's return value. If the + attribute's value is the empty string, the <literal>GError + *</literal> argument is also omitted so there is no standard way + to return an error value. This is very useful for interfacing + with existing code, as it is possible to match existing APIs. + If the attribute's value is <literal>"error"</literal>, then the + final argument is a <literal>GError *</literal> as usual. + </para> + <para> + Some examples to demonstrate the usage. This introspection XML: + <programlisting> +<method name="Increment"> + <arg type="u" name="x" /> + <arg type="u" direction="out" /> +</method> + </programlisting> + Expects the following function declaration: + <programlisting> +gboolean +my_object_increment (MyObject *obj, gint32 x, gint32 *ret, GError **error); + </programlisting> + </para> + <para> + This introspection XML: + <programlisting> +<method name="IncrementRetval"> + <arg type="u" name="x" /> + <arg type="u" direction="out" > + <annotation name="org.freedesktop.DBus.GLib.ReturnVal" value=""/> + </arg> +</method> + </programlisting> + Expects the following function declaration: + <programlisting> +gint32 +my_object_increment_retval (MyObject *obj, gint32 x) + </programlisting> + </para> + <para> + This introspection XML: + <programlisting> +<method name="IncrementRetvalError"> + <arg type="u" name="x" /> + <arg type="u" direction="out" > + <annotation name="org.freedesktop.DBus.GLib.ReturnVal" value="error"/> + </arg> +</method> + </programlisting> + Expects the following function declaration: + <programlisting> +gint32 +my_object_increment_retval_error (MyObject *obj, gint32 x, GError **error) + </programlisting> + </para> + </listitem> + </varlistentry> + </variablelist> + </para> + </sect2> </sect1> <sect1 id="python-client"> |