Re: Problems with GHashTable in signal handler





On Sun, Oct 25, 2009 at 10:40 PM, muppet <scott asofyet org> wrote:

On Oct 25, 2009, at 8:55 AM, JÃrn Reder wrote:

Hi,

I try to use the "create-plugin-widget" signal of Gtk2::WebKit::WebView,
which passes a GHashTable to the callback. Here it's signature from the
docs:

ÂGtkWidget* user_function (WebKitWebView *web_view,
             gchar     *mime_type,
             gchar     *uri,
             GHashTable  Â*param,
             gpointer    user_data) : Run Last / Action

Â(from http://webkitgtk.org/reference/webkitgtk-WebKitWebView.html#WebKitWebView-create-plugin-widgetÂ)

Perl dies with this error message when my signal handler is called:

ÂGType GHashTable (146176672) is not registered with gperl

Since signal handling is completely covered on Glib level I don't think
this problem is related to Gtk2::WebKit. The Glib perldoc says
GHashTable is bound to the native Perl hash datatype. I grep'ed the
sources of Glib and Gtk2 to find any examples of passing GHashTables to
Perl - with no luck.

Any help on this is appreciated ;)


Actually, the docs say "The GLib types GList (a doubly-linked list), GSList (singly-linked list), GHashTable, GArray, etc have all been replaced by native Perl datatypes." ÂThat is, "replace by", not "bound to." ÂGHashTable is not really bindable, because it is a generic mapping of arbitrary pointer to arbitrary pointer; you must know something about what is in it in order to use it, and we can't create a generic wrapper for that. ÂTherefore, for each function that passes a hash table, we map that by hand to a perl hash.

However, it's not actually very common for the gnome APIs to pass GHashTables around -- they're normally used for implementation. ÂIn fact, i can't really think of where we've had to do this...


libgobject started registering a GType for GHashTable in 2.10, to make it possible to say "this signal argument is a hash table" instead of "this signal argument is a pointer". ÂHowever, as the gobject-introspection guys pointed out, this isn't terribly useful; you need to know more information, like "this object is a hash table whose keys are strings and whose values are gobjects". ÂWe don't have that at a generic level.


So the only real option that you have is to create a custom marshaller for this signal, implemented in Gtk2::WebKit::WebView. ÂThis marshaller would be used only for this signal, where we know that the hash table is supposed to be a map of strings to strings. ÂYou'd do something like call g_hash_table_foreach() to push all the keys and values in the hash table into a new hash, and pass a reference to that new hash to perl in place of the hash table. Â(The closer you stick to the C api, the fewer problems people will have here.) ÂIf you're supposed to allow the callback to modify the hash, then you'll have to push those changes back the other way when the callback returns.

Read gperl_marshal.h for a template and helpers. ÂThere are a few examples of custom marshallers in Gtk2, nearly all used for arguments that are unfriendly to non-C languages (e.g. write-through integer parameters, C arrays, and G_TYPE_POINTER args that you're supposed to cast to something else). ÂSearch Gtk2 for gperl_signal_set_marshaller_for and follow where that takes you.

>From Glib::xsapi:

 void gperl_signal_set_marshaller_for (GType instance_type, char * detailed_signal, GClosureMarshal marshaller)

  ÂYou need this function only in rare cases, usually as workarounds
   for bad signal parameter types or to implement writable arguments.
   Use the given marshaller to marshal all handlers for detailed_sig-
   nal on instance_type. Â"gperl_signal_connect" will look for mar-
   shallers registered here, and apply them to the GPerlClosure it
   creates for the given callback being connected.

   Use the helper macros in gperl_marshal.h to help write your mar-
   shaller function. ÂThat header, which is installed with the Glib
   module but not #included through gperl.h, includes commentary and
   examples which you should follow closely to avoid nasty bugs. ÂUse
   the Source, Luke.
Thanks for the explanation! This has come very handy as I was wondering how this could be done. I always wanted to change a parameter in Gtk2::Unique and didn't knew that it was even possible until you wrote this :)

I've now implemented this for Gtk2::Unique which now looks more Perl-ish than ever!
Â
Emmanuel Rodriguez


[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]