Re: generic refcounted object perl binding
- From: Torsten Schoenfeld <kaffeetisch gmx de>
- To: gtk-perl-list gnome org
- Subject: Re: generic refcounted object perl binding
- Date: Wed, 26 Oct 2011 10:20:11 +0200
On 26.10.2011 07:49, YangXi wrote:
Another question about wrapper design, in function gperl_new_object()
where an new wrapper is newly created:
......
obj = (SV *)g_object_get_qdata (object, wrapper_quark);
if (!obj) {
......
// created a hash
obj = (SV *)newHV () ;
_gperl_attach_mg (obj, object);
g_object_ref (object);
// created a SV wrapper for the hash
sv = newRV_noinc (obj);
sv_bless (sv, stash);
......
}
......
Why don't bless the HV directly, but instead creating another SV
wrapping the HV, and bless that SV instead?
That is how references work at the perl C API level, but also kind of
how they work in Perl directly. A reference to something is a separate
SV (with its own refcount, etc.), just like in Perl, where you can take
multiple references to the same variable. And if you to put something
into some namespace, you have to bless the reference, not the referent.
Why use noinc to create the wrapper? Shouldn't the SV wrapper holding a
reference for HV?
This is a common pattern when constructing references: we use
newRV_noinc as opposed to newRV because 'obj' from above is a new HV and
we want 'sv' to take ownership of the initial refcount. Thus, when 'sv'
goes out of scope it would normally take 'obj' with it. In Glib::Object
this is a bit more complicated because we want 'obj' to survive so that
we can find it later and hand it out again. This is done by
incrementing its refcount in Glib::Object::DESTROY (which is called when
'sv' goes out of scope).
I wanted to link to some XS tutorial covering all this, but the example
at <http://perldoc.perl.org/perlxstut.html#EXAMPLE-6> actually uses a
different pattern to achieve the same thing: it mortalizes both the
referent and the reference, so when the xsub returns both end up having
refcount=1 as well. (The sv_2mortal call for the reference is hidden in
the 'SV*' typemap.)
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]