[Date Prev][Date Next] [Thread Prev][Thread Next]
Re: [Libguestfs] GObject bindings overview
- From: "Richard W.M. Jones" <rjones redhat com>
- To: Matthew Booth <mbooth redhat com>
- Cc: Libguestfs <libguestfs redhat com>
- Subject: Re: [Libguestfs] GObject bindings overview
- Date: Fri, 20 Jan 2012 13:44:10 +0000
On Fri, Jan 20, 2012 at 12:07:47PM +0000, Matthew Booth wrote:
> I've summarised how the GObject bindings work below, which should
> hopefully help reviewing the generator/generated code.
> There are a couple of points in here I'm still not 100% happy with.
> Specifically the handling of FBuffer and the Cancellable flag. Both
> are explained below. I'm interested in suggestions.
> Return values:
> All functions which can return an error have as their final argument
> a GError **. GI maps this to the appropriate error mechanism for
> each target language.
> RErr returns a gboolean, true = success, false = failure.
> The following types return the value from libguestfs unchanged:
> RConstString (transfer none): gobject doesn't manage returned memory
> RConstOptString (transfer none). Methods don't return an error (no
> RHashtable is converted to a GHashTable. The keys and values from
> libguestfs are inserted directly into the GHashTable without
> copying. The top level array returned by libguestfs is freed.
It could be useful to run the gobject tests under valgrind.
> RStruct is converted to GObject boxed type for the target struct. It
> returns a copy of the struct, which is copied field by field. Memory
> for the returned struct is allocated using glib's slice allocator.
> The original struct is freed with guestfs_free_<struct>().
> RStructList is converted as an array of structs, which are
> individually converted the same way as RStruct, i.e. everything is
> copied. The returned array is a newly allocated NULL-terminated
> array. The originally returned value is freed with
> RBufferOut is returned as a guint8 array, whose length is specified
> by a size_r field. GObject uses both these fields to construct a
> single array object where language bindings allow. The value
> returned by RBufferOut is not copied.
> A parallel struct is created for each libguestfs struct type. A
> boxed type is created for each parallel struct. It's field types are
> all mapped trivially to gobject basic types (e.g. gchar *, gint32)
> except FBuffer. FBuffer is mapped as:
> guint8 *<field>
> guint32 <field>_size
> Unfortunately I can see no way to attach annotation to these fields,
> so the bindings do not appreciate that these fields are related. I'm
> not happy with this at all, so I may try manual tweaking of the .gir
> to see if we can turn these into a single returned array where
> Required arguments:
> Required arguments to methods are all mapped trivially to gobject
> basic types. They are all passed directly to libguestfs. StringList
> and DeviceList both remain null-terminated arrays. BufferIn has
> separate array and length components, which are combined into a
> single array using annotations where language bindings permit.
> Optional arguments:
> Optional arguments are implemented as a separate gobject whose name
> is is Guestfs<camel api name>. This gobject has defined properties
> for each optional argument accepted by the api. All properties are
> initially undefined. Property types are mapped as:
> OBool -> GuestfsTristate
> OInt, OInt64 -> gint/gint64. -1 is used internally as a magic
> value to represent undefined.
> OString -> gchar *. NULL represents undefined.
> GuestfsTristate is a new boxed enum type with values FALSE, TRUE and
> 'false' here works as expected. To set the UNSET value, you have to
> explicitly use GuestfsTristate.UNSET.
> OInt and OInt64 have a similar problem to boolean, in that there's
> no way to represent unset in the fundamental type. The -1 =
> undefined scheme is an internal detail and need not be part of the
> API. I did create a patch to make the undefined number explicit for
> each optional argument which required it. However I decided to hold
> off on it until we actually create an api where this would be a
> problem, as it makes the api definition in the generator slightly
> uglier and more complex.
> Where no optional arguments are required, the user can pass in the
> binding language's equivalent of NULL. GObject has a placeholder for
> default values, but there are not yet implemented. When they are, we
> can define the default value of optargs to be null, meaning they can
> be entirely omitted when not required.
> Certain apis are cancellable. These all take a GCancellable as the
> final argument before GError **. This can be passed NULL if
> cancellation is not required. While I have written cancellation, I
> have not yet tested it *at all* other than it compiles and works
> correctly when NULL is passed in.
> We recently made Cancellable an explicit flag whereas before it was
> implicit if the api had a FileIn or FileOut argument. This means it
> is now possible to break the GObject api without breaking the C api
> with the addition of a Cancellable flag. What potential solutions
> are there to this problem? I can see:
> • Live with breaking the GObject api if it ever comes up.
> • Never add Cancellable to an existing api.
> • Automatically add a GCancellable argument to all GObject apis,
> just in case.
The right way is to add a check to generator_checks.ml which
ensures that presence of FileIn/FileOut === Cancellable flag
> Events API
> The libguestfs events API is not yet bound. I'll add this at a later stage.
Richard Jones, Virtualization Group, Red Hat http://people.redhat.com/~rjones
virt-p2v converts physical machines to virtual machines. Boot with a
live CD or over the network (PXE) and turn machines into Xen guests.
[Date Prev][Date Next] [Thread Prev][Thread Next]