Re: How is this handled in gtk perl?




Ari Jolma said:
Is this issue an issue in gtk-perl bindings and/or how it was fixed or
dealt with? Do you have any recommendations/ideas? Of course the swig is
an added complication and the need to support more languages that Perl.

The design document for gtk2-perl-xs describes a bit of the philosophy on
reference-counting and the bindings, but the actual details are a little out
of date:
http://gtk2-perl.sourceforge.net/doc/new-gtk2-perl.html

There are two basic techniques:

a) the perl object contains an integer which is actually the pointer value:
  i) reference to a scalar, and the scalar contains the pointer value.
  ii) reference to a hash with a special key containing the pointer value.
This approach is common in perl-land, but is easily broken by people
overwriting the special hash key, or changing the pointer value.

b) attach the pointer to the perl object with "magic".  This technique is
completely transparent to the perl developer, and can't be broken from perl,
but is a little harder to pull off.


Gtk2-Perl uses a) for basic boxed types, and b) for GObjects.


The actual code to bind GObject to Glib::Object does some fancy tricks
involving "borrowing" reference counts between C and perl objects to ensure
that perl object lives as long as the C object, even if the perl code doesn't
actually own the object.  For example:

   # assume Foo and Bar are Glib::Object classes.
   my $global_bar = new Bar;  # reference count 1
   {
      my $foo = new Foo;  # reference count 1
      my $bar = new Bar;  # reference count 1

      $global_bar->set_foo ($foo);  # foo's reference count goes up

      $foo->{some_key} = 'whee!";

      # end of block, both $foo and $bar go out of scope.
      # $bar and its underlying GObject should die.
      # $foo will not longer be a valid perl variable name, but
      # the underlying GObject *and the perl wrapper* should not die!
   }
   # $global_bar's foo should be exactly the same perl and C object
   # as in the block above.
   assert ($global_bar->get_foo->{some_key} eq 'whee!');


To achieve this unified perl&C object, the bindings actually set up a
self-referential system where the C object is attached to the perl object via
magic (see MAGIC Virtual Tables in perlguts), and the perl object is attached
to the C object via GObject user data.  Not all systems will have the generic
"attach any pointer to a key" system that GObject has, so your mileage may
vary.


I don't think i'm answering you clearly.  Please insert caffeine and ask more
questions.


-- 
muppet <scott at asofyet dot org>




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