Service-Side GLib Bindings

Havoc Pennington hp at redhat.com
Sun Aug 15 10:00:52 PDT 2004


On Sat, 2004-08-14 at 17:31, Paul Kuliniewicz wrote:
> I've been looking at what's left to implement to get the service-side
> functionality of the GLib bindings operational,

Yay!

Scan through doc/TODO, though there's nothing earth-shattering in there.

I'm assuming you've seen mails on the general plan, which was to go:

 sourcecode parser -> XML format -> generated metadata file

and then in the object implementation file:

#include <generated metadata file>

class_init ()
{
  dbus_g_object_class_install_info (klass, 
                                    object_info_from_metadata_file);
}

I would skip the "sourcecode parser" piece for now and just do the XML
to metadata converter thingy. Also, "sourcecode parser" can be replaced
with "IDL parser" or whatever else. The structure of dbus-glib-tool is
probably that it converts everything to the dbus-gidl.h tree data
structure and then proceeds from there to any known output formats
including the DBusGObjectInfo.

> What's the purpose of the <node> tags in the XML introspection data?
> All of the other tags are pretty straightforward, but I'm not sure what
> <node> represents.  An example of what this XML introspection data
> should look like would be great.

The idea is that you can query a tree of objects in the object path
tree, e.g. all children of /foo/bar in one go.

Unfortunately the example XML file I used to test the parser got lost -
I should have checked it in to cvs ;-) at this point I'd have to
reverse-engineer it again from the code. The right file to do this from
is dbus-gparser.c. dbus-gidl.h shows conceptually what the XML
represents.

> How should gobject_message_function() figure out what function needs to
> be called?  I suppose the marshaller field in DBusGMethodInfo is the
> function that unpacks the message's parameters, makes the actual call,
> packs the return value(s) into the reply message, and sends it.  But how
> can the right DBusGMethodInfo be found, since it doesn't store the name
> of the method it implements?
> 
> Also, what is the data field in DBusGObjectInfo for?  The XML
> introspection data?

You should assume that MethodInfo/ObjectInfo could be totally wrong -
they were just some initial sketches at how it might work.
The goal should be to have a minimum number of static variables
representing the metainfo/type-library, and have each of those variables
be read-only (const) data. This will make things much more efficient.
Runtime speed is probably a secondary goal, within reason.

That said, I'll explain what the initial sketch was supposed to mean:

 - GObjectInfo::data is a huge const string with the method names and  
   signatures. I don't know what format it's in, that's TBD.
 - GMethodInfo has the function pointer, the marshaller, and an 
   offset into the huge const string
 - all the GMethodInfo are in a big const array, pointed to be 
   GObjectInfo

So the generated data might look like:

static const char object_info_data[] =
"some_method_name,whatever,whatever,another_method_name,whatever";

static const GMethodInfo object_method_infos[] = {
  { c_function_name, marshaller_for_this_function, 0 },
  { other_c_function_name, another_marshaller, 20 },
  { NULL, NULL, 0 }
};

static const GObjectInfo object_info = { 
  0, /* version */
  object_method_infos,
  object_info_data
};

Also generated would be any needed marshallers (the common marshallers
might be included in libdbus-glib, and then uncommon ones have a
separate copy in each generated file). 

It's possible the object_info_data string only has method names I guess,
since the method type signatures are known to the marshaller.

The obvious approach would be to have GMethodInfo include the method
name. However, this creates a bunch of extra symbols in the object file,
and has a noticeable impact on app startup time. Qt 4 moves to the "one
huge string" approach for that reason, we may as well copy the good
idea.

> How do an object's signals get transformed into D-BUS signals?

I think just straightforwardly: emit a D-BUS signal with the same name.

>   Will the
> bindings need to add listeners for each exposed signal on the object?

Yep. I guess this might have to be part of the GObjectInfo, there's
nothing in there yet about signals.

> And, finally, a non-implementation question.  D-BUS methods usually have
> names that LookLikeThis, but GLib methods have names that
> look_like_this.  Which naming convention is the "right one" to use for
> GLib methods exposed by D-BUS?

I was converting between them, see wincaps_to_uscore(). Which is kind of
strange, but seems right to me. The general principle here is that you
have to write the GObject following certain conventions to make it work
as a D-BUS remote object, and so one of the conventions may as well be
that it sensibly autoconverts to wincaps.

A final note, I think you'll have to add some stuff to the XML format,
namely for methods you'll need a c_method_name attribute I bet. This
would be in the XML format used for this purpose but not returned from
an Introspect() call.

Good luck, please ask questions, I'm happy to help get this done.

Havoc




More information about the dbus mailing list