[PATCH] Non-working support for GObject Introspection.
Read the README file at the top of this patch first. Problems I see with GObject Introspection: (1) Requires that your code uses GObject; obvious in hindsight given the name. In this case, it seems that we'd have to "register" the guestfs_h structure with GObject (whatever that means). (2) Cannot convert C error codes into exceptions automatically. So all your high level code has to check return values -- ugh. (3) Poor type system (although at least it does have a concept of non-nullable types). For example, you cannot express 31 bit ints, or range types, dependent types, constructed types, etc etc etc. So I think it's OK if your code depends on glib, but for general C interfaces I cannot see this catching on at the moment. Rich. -- 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. http://et.redhat.com/~rjones/virt-p2v
On Tue, Mar 16, 2010 at 02:42:27PM +0000, Richard W.M. Jones wrote:
+GObject Introspection bindings +------------------------------ + +Although we add the necessary annotations for GObject Introspection to +the <guestfs*.h> header files, we have not yet had satisfactory +results using them. + +In theory this should allow you to call libguestfs from languages +which we don't yet support, notably Javascript (using GJS or Seed). + +Here is how you can build the GIR bindings. First you have to build +libguestfs normally, then: + + cd gir + g-ir-scanner -n Guestfs --nsversion 0.0 \ + -L ../src/.libs -lguestfs \ + ../src/guestfs.h > Guestfs-0.0.gir + g-ir-compiler Guestfs-0.0.gir > Guestfs-0.0.typelib + +If that went OK, then copy 'Guestfs-0.0.typelib' into the public +directory '/usr/lib{,64}/girepository-1.0/' (or you can make a symlink +which works just as well). + +In theory you should be able to use this immediately from gjs-console: + + LIBGUESTFS_DEBUG=1 gjs-console + gjs> const Guestfs = imports.gi.Guestfs; + gjs> g = Guestfs.create (); + +Currently this gives the following error: + + new guestfs handle 0x2537d00 + Error: No exception was set, but object construction failed somehow + +Because the 'new guestfs handle 0x..' debug message was printed, we +know in fact that construction succeeded! + +It seems we need to "register" the guestfs_h handle with GObject. I +can't get any straight answer to how that would be done.
GObject is the primary root object, but things don't neccessarily need to inherit from GObject. Since you're trying to directly expose libguestfs' own object(s) you'll probably need to register them as base types using the GType APIs. This section of the API docs gives a semi-useful intro to GTypes http://library.gnome.org/devel/gobject/stable/chapter-gtype.html Ultimately this comes down to a call to g_type_register_static() http://library.gnome.org/devel/gobject/stable/gobject-Type-Information.html#... but it is not very well documented because 99% of apps just inherit from GObject instead of introducing new base types like libguestfs would need todo. Regards, Daniel -- |: Red Hat, Engineering, London -o- http://people.redhat.com/berrange/ :| |: http://libvirt.org -o- http://virt-manager.org -o- http://deltacloud.org :| |: http://autobuild.org -o- http://search.cpan.org/~danberr/ :| |: GnuPG: 7D3B9505 -o- F3C9 553F A1DA 4AC2 5648 23C1 B3DF F742 7D3B 9505 :|
On Tue, Mar 16, 2010 at 02:53:29PM +0000, Daniel P. Berrange wrote:
GObject is the primary root object, but things don't neccessarily need to inherit from GObject. Since you're trying to directly expose libguestfs' own object(s) you'll probably need to register them as base types using the GType APIs. This section of the API docs gives a semi-useful intro to GTypes
http://library.gnome.org/devel/gobject/stable/chapter-gtype.html
Ultimately this comes down to a call to g_type_register_static()
http://library.gnome.org/devel/gobject/stable/gobject-Type-Information.html#...
but it is not very well documented because 99% of apps just inherit from GObject instead of introducing new base types like libguestfs would need todo.
Unfortunately this doesn't work. The handle (guestfs_h *) is wrapped inside a GType: typedef struct _GuestfsH { GObject parent; guestfs_h *h; } GuestfsH; I can now register this easily enough, but GObject won't automatically unpack that handle when it passes it to the other functions. ie. The other functions would receive a GuestfsH, instead of a guestfs_h *, and they won't know what to do with the former. Rich. -- Richard Jones, Virtualization Group, Red Hat http://people.redhat.com/~rjones libguestfs lets you edit virtual machines. Supports shell scripting, bindings from many languages. http://et.redhat.com/~rjones/libguestfs/ See what it can do: http://et.redhat.com/~rjones/libguestfs/recipes.html
On Tue, Mar 16, 2010 at 03:45:17PM +0000, Richard W.M. Jones wrote:
On Tue, Mar 16, 2010 at 02:53:29PM +0000, Daniel P. Berrange wrote:
GObject is the primary root object, but things don't neccessarily need to inherit from GObject. Since you're trying to directly expose libguestfs' own object(s) you'll probably need to register them as base types using the GType APIs. This section of the API docs gives a semi-useful intro to GTypes
http://library.gnome.org/devel/gobject/stable/chapter-gtype.html
Ultimately this comes down to a call to g_type_register_static()
http://library.gnome.org/devel/gobject/stable/gobject-Type-Information.html#...
but it is not very well documented because 99% of apps just inherit from GObject instead of introducing new base types like libguestfs would need todo.
Unfortunately this doesn't work. The handle (guestfs_h *) is wrapped inside a GType:
typedef struct _GuestfsH { GObject parent; guestfs_h *h; } GuestfsH;
I can now register this easily enough, but GObject won't automatically unpack that handle when it passes it to the other functions. ie. The other functions would receive a GuestfsH, instead of a guestfs_h *, and they won't know what to do with the former.
Oh I see - this struct is actually attempting to create a GObject subclass containing a guestfs_h *. This definitely don't work, because of the mis-matched ptrs you mention. I thought you were registering 'guestfs_h *' itself as the type without the 'struct _GuestfsH' wrapper. This avoids GObject entirely introducing a new base type. Daniel -- |: Red Hat, Engineering, London -o- http://people.redhat.com/berrange/ :| |: http://libvirt.org -o- http://virt-manager.org -o- http://deltacloud.org :| |: http://autobuild.org -o- http://search.cpan.org/~danberr/ :| |: GnuPG: 7D3B9505 -o- F3C9 553F A1DA 4AC2 5648 23C1 B3DF F742 7D3B 9505 :|
On Tue, Mar 16, 2010 at 03:49:21PM +0000, Daniel P. Berrange wrote:
Oh I see - this struct is actually attempting to create a GObject subclass containing a guestfs_h *. This definitely don't work, because of the mis-matched ptrs you mention. I thought you were registering 'guestfs_h *' itself as the type without the 'struct _GuestfsH' wrapper. This avoids GObject entirely introducing a new base type.
I'll try that ... We're quite far outside the realms of what has been tried before with gobject though ... Rich. -- Richard Jones, Virtualization Group, Red Hat http://people.redhat.com/~rjones Read my programming blog: http://rwmj.wordpress.com Fedora now supports 80 OCaml packages (the OPEN alternative to F#) http://cocan.org/getting_started_with_ocaml_on_red_hat_and_fedora
On Tue, Mar 16, 2010 at 03:49:21PM +0000, Daniel P. Berrange wrote:
On Tue, Mar 16, 2010 at 03:45:17PM +0000, Richard W.M. Jones wrote:
On Tue, Mar 16, 2010 at 02:53:29PM +0000, Daniel P. Berrange wrote:
GObject is the primary root object, but things don't neccessarily need to inherit from GObject. Since you're trying to directly expose libguestfs' own object(s) you'll probably need to register them as base types using the GType APIs. This section of the API docs gives a semi-useful intro to GTypes
http://library.gnome.org/devel/gobject/stable/chapter-gtype.html
Ultimately this comes down to a call to g_type_register_static()
http://library.gnome.org/devel/gobject/stable/gobject-Type-Information.html#...
but it is not very well documented because 99% of apps just inherit from GObject instead of introducing new base types like libguestfs would need todo.
Unfortunately this doesn't work. The handle (guestfs_h *) is wrapped inside a GType:
typedef struct _GuestfsH { GObject parent; guestfs_h *h; } GuestfsH;
I can now register this easily enough, but GObject won't automatically unpack that handle when it passes it to the other functions. ie. The other functions would receive a GuestfsH, instead of a guestfs_h *, and they won't know what to do with the former.
Oh I see - this struct is actually attempting to create a GObject subclass containing a guestfs_h *. This definitely don't work, because of the mis-matched ptrs you mention. I thought you were registering 'guestfs_h *' itself as the type without the 'struct _GuestfsH' wrapper. This avoids GObject entirely introducing a new base type.
Actually this won't work either because of this 2nd requirement from GType 1. All class structures must contain as first member a GTypeClass structure. 2. All instance structures must contain as first member a GTypeInstance structure. So AFAICT, the only option would be to generate a guestfs-glib library which had a full set of wrappers around every C API, that accept 'struct _GuestfsH' instead of 'guestfs_h' and de-refernce the ->h field before calling the real libguestfs APIs. Daniel -- |: Red Hat, Engineering, London -o- http://people.redhat.com/berrange/ :| |: http://libvirt.org -o- http://virt-manager.org -o- http://deltacloud.org :| |: http://autobuild.org -o- http://search.cpan.org/~danberr/ :| |: GnuPG: 7D3B9505 -o- F3C9 553F A1DA 4AC2 5648 23C1 B3DF F742 7D3B 9505 :|
On Tue, Mar 16, 2010 at 03:54:05PM +0000, Daniel P. Berrange wrote:
Actually this won't work either because of this 2nd requirement from GType
1. All class structures must contain as first member a GTypeClass structure. 2. All instance structures must contain as first member a GTypeInstance structure.
I guess we could put some padding at the beginning of the real guestfs_h structure. It shouldn't break the ABI because no callers should be looking inside the guestfs_h structure. The current _GTypeInstance just contains a single pointer, so 8 bytes of padding ought to do it ... Rich. -- 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. http://et.redhat.com/~rjones/virt-p2v
On Tue, Mar 16, 2010 at 03:58:57PM +0000, Richard W.M. Jones wrote:
On Tue, Mar 16, 2010 at 03:54:05PM +0000, Daniel P. Berrange wrote:
Actually this won't work either because of this 2nd requirement from GType
1. All class structures must contain as first member a GTypeClass structure. 2. All instance structures must contain as first member a GTypeInstance structure.
I guess we could put some padding at the beginning of the real guestfs_h structure. It shouldn't break the ABI because no callers should be looking inside the guestfs_h structure.
The current _GTypeInstance just contains a single pointer, so 8 bytes of padding ought to do it ...
This is a bit trickier than it looks. GObject needs to know the size of the structure, and obviously we don't expose this. If we expose it through a libguestfs API call, then there seems to be the danger that GObject could try to move / duplicate the structure. That would break libguestfs because we maintain a list of pointers to open handles internally. I think I'll leave this for now. Rich. -- Richard Jones, Virtualization Group, Red Hat http://people.redhat.com/~rjones New in Fedora 11: Fedora Windows cross-compiler. Compile Windows programs, test, and build Windows installers. Over 70 libraries supprt'd http://fedoraproject.org/wiki/MinGW http://www.annexia.org/fedora_mingw
participants (2)
-
Daniel P. Berrange -
Richard W.M. Jones