Re: Problems with GHashTable in signal handler
- From: muppet <scott asofyet org>
- To: Jörn Reder <joern zyn de>
- Cc: Gtk Perl List <gtk-perl-list gnome org>, Florian Ragwitz <rafl debian org>
- Subject: Re: Problems with GHashTable in signal handler
- Date: Sun, 25 Oct 2009 17:40:05 -0400
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.
WARNING: Bend over backwards and turn your head around 720
degrees
before attempting to write a GPerlClosure marshaller without
using
the macros in gperl_marshal.h. If you absolutely cannot use
those
macros, be certain to understand what those macros do so you can
get the semantics correct, and keep your code synchronized with
them, or you may miss very important bugfixes.
--
Me: What's that in your mouth?
Zella: *swallows laboriously* Nothing.
Me: What did you just swallow?
Zella: A booger.
Me: Baby girl, don't eat boogers. That's gross.
Zella: But it was in my nose.
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]