Re: pygi: callback funcs and GErrors
- From: Laszlo Pandy <laszlok2 gmail com>
- To: Christophe Saout <christophe saout de>
- Cc: python-hackers-list gnome org
- Subject: Re: pygi: callback funcs and GErrors
- Date: Fri, 18 Feb 2011 21:15:17 +0100
So if you "return False, None" from the callback, None becomes the
GError and it is considered set (I guess because None is a Python
object and not NULL).
Then Pixbuf.save_to_callbackv() sets the GError and returns in
failure. There is a bug in PyGObject introspection for handling
cleanup of arrays when a GError is set. I've reported it, until the
invoke experts decide how best to solve it:
https://bugzilla.gnome.org/show_bug.cgi?id=642708
On Tue, Feb 15, 2011 at 1:54 PM, Christophe Saout <christophe saout de> wrote:
> Dear python hackers,
>
> I am having some troubles with the new Python bindings via the amazing
> gobject-introspection project:
>
> My attempts to use "gdk_pixbuf_save_to_callback" via
> gobject-introspection and gi.repository so far have failed.
>
> Note that the exact same thing is working with the classic pygtk & co
> bindings, however I have good reasons to port this to the new system. (I
> have started writing additional modules where I want to use the
> pygi-style bindings) And yes, I am aware that this is still kind of
> experimental, so I'd like to report my observations.
>
> It seems like the annotations added so far are mostly to keep the
> scanner happy. I've tried to fix up the annotations to get things
> going, but I am running into a few problems:
>
> The method is defined as follows:
>
> gboolean gdk_pixbuf_save_to_callback (GdkPixbuf *pixbuf,
> GdkPixbufSaveFunc save_func,
> gpointer user_data,
> const char *type,
> GError **error,
> ...) G_GNUC_NULL_TERMINATED;
>
> Well, this one doesn't seem to want to work at all (probably due to
> varargs) - it doesn't even show up as a possible method from python.
>
> So I concentrated on its twin:
>
> gboolean gdk_pixbuf_save_to_callbackv (GdkPixbuf *pixbuf,
> GdkPixbufSaveFunc save_func,
> gpointer user_data,
> const char *type,
> char **option_keys,
> char **option_values,
> GError **error);
>
> with the callback func declared as:
>
> typedef gboolean (*GdkPixbufSaveFunc) (const gchar *buf,
> gsize count,
> GError **error,
> gpointer data);
>
> I've tried to fix up the annotation as follows:
>
> /**
> * gdk_pixbuf_save_to_callbackv:
> * @pixbuf: a #GdkPixbuf.
> * @save_func: (scope call): a function that is called to save each block of data that
> * the save routine generates.
> * @user_data: (closure save_func): user data to pass to @save_func
> * @type: name of file format.
> * @option_keys: (array zero-terminated=1) (element-type utf8): name of options to set, %NULL-terminated
> * @option_values: (array zero-terminated=1) (element-type utf8): values for named options
> * @error: (allow-none): location to store error, or %NULL.
> *
> * Saves pixbuf to a callback in format @type, which is currently "jpeg",
> * "png", "tiff", "ico" or "bmp". If @error is set, %FALSE will be returned. See
> * gdk_pixbuf_save_to_callback () for more details.
> *
> * Return value: whether an error was set
> *
> * Since: 2.4
> **/
>
> Issues:
>
> * Not sure about option_values and being zero-terminated. It should
> have the same size as option_keys (where the zero-termination is
> explicitly stated). I guess I can't tell it I want to have the same
> size as another array? However, that's not my main issue, I just
> wondered.
>
> * I've added the (scope call) and (closure save_func) to save_func /
> user_data
>
> Now when calling that method from python it was telling me:
> app1:/root # python test.py
> ERROR:pygi-argument.c:1717:_pygi_argument_to_object: code should not be
> reached
>
> Which I traced down to the GError in GdkPixbufSaveFunc. Apparently it
> was thinking this is a parameter that is being passed in (instead of
> automatically seeing that it's an error that can be thrown from inside
> the closure)
>
> So as a workaroung I tried to annotate the SaveFunc as follows:
>
> /**
> * GdkPixbufSaveFunc:
> * @buf:
> * @count:
> * @error: (out)
> * @data: (closure):
> */
>
> Now my callback is actually being called:
> ('\x89PNG\r\n\x1a\n\xc8\xb1\xde\x01', 8L, None)
>
> But afterwards I get:
>
> ERROR:pygi-closure.c:307:_pygi_closure_set_out_arguments: code should
> not be reached
>
> Which presumably is a problem with the GError now being an output
> parameter? (the Python function has a "return False")
>
> Changing that one to "return (False, None)" gives
>
> Program received signal SIGSEGV, Segmentation fault.
> 0x00007ffff7d99ae7 in _pygi_argument_release ()
> from /usr/lib64/python2.7/site-packages/gi/_gi.so
> (gdb) bt
> #0 0x00007ffff7d99ae7 in _pygi_argument_release ()
> from /usr/lib64/python2.7/site-packages/gi/_gi.so
> #1 0x00007ffff7d99b7e in _pygi_argument_release ()
> from /usr/lib64/python2.7/site-packages/gi/_gi.so
> #2 0x00007ffff7d963c0 in _free_invocation_state ()
> from /usr/lib64/python2.7/site-packages/gi/_gi.so
> #3 0x00007ffff7d978ac in _wrap_g_callable_info_invoke ()
> [...]
>
> Also one further question:
>
> * Is it possible t have the (buffer, size) parameters be turned into a
> single argument on the Python side? I'm afraid that passing binary
> data from C to Python this way, the converter will look for a
> null-terminated string instead of making the buffer exactly the
> indicated size.
>
> Oh, and in case you haven't noticed, this function is from the
> gdk-pixbuf package.
>
> Software versions used:
>
> glib 2.28.0
> gobject-introspection 0.10.2
> python 2.7.1
> pygobject 2.90.0
>
> Python test code:
>
> from gi.repository import GdkPixbuf
> x = GdkPixbuf.Pixbuf.new(GdkPixbuf.Colorspace.RGB, False, 8, 100, 100)
>
> def cb(*args):
> print args
> return False
>
> x.save_to_callbackv(cb, None, 'png', [], [])
>
> I am trying to write a small web service that renders images to a png or
> something like that and then transmits those directly over the network.
>
> Thanks a lot,
>
> Christophe
>
>
> _______________________________________________
> python-hackers-list mailing list
> python-hackers-list gnome org
> http://mail.gnome.org/mailman/listinfo/python-hackers-list
>
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]