Using Tie in XSUBs

Do you have a question? Post it now! No Registration Necessary.  Now with pictures!

Threaded View


I wrote a tied array implementation as an XSUB. The XSUB module
contains other packages as well. From a method of a package
I want to return a tied arrayref of my own tied array class,
something like that (expressed in Perl code):

package Foo;
sub get_list {
   my $self = shift;
   my @a;
   tie @a, 'Foo::Array', @_; # how do I implement that in C??
   return \@a;

package Foo::Array;
sub TIEARRAY { ... }
sub FETCH { ... }

I read the section "Understanding the Magic of Tied Hashes and
Arrays" of perlguts, but, despite its name, it covers only hashes.
Not that I unterstood it either ;-)


Re: Using Tie in XSUBs

Also sprach Robert Jordan:

Quoted text here. Click to load it

For some things in XS it is best to consult the perl source for
reference, in this case pp_tie().

I think for a tied array you have to do this [untested]:

    tie_this (av)
        SV *av;
        /* create blessed array-reference */
        HV *stash = gv_stashpv("Foo::Array", TRUE);
        SV *sv = newRV_noinc((SV*)newAV());
        sv_bless(sv, stash);
        /* make av a blessed array associated with
         * sv as its internal object               */
        sv_magic(SvRV(av), sv, PERL_MAGIC_tied, Nullch, 0);
'sv' in the above might need to be mortalized, not sure right now.

The above gets away without any TIEARRAY method. All the other methods
(FETCH, etc.) you can define as ordinary XSUBs which will receive 'sv'
as their first argument.

Usage is simple:

    tie_this(my @array);
    # @array should now be tied

use bigint;

Re: Using Tie in XSUBs


Quoted text here. Click to load it

Wow, call me an idiot ;-) I didn't realize that AVs are upgraded
with sv_magic() as well. I sorted that out with the help of
the perl sources and of your sample:

/* create AV ref */    
AV *ref = newRV_noinc ((SV *) newAV ());

/* tie the AV with the already blessed `obj' */
sv_magic (SvRV (ref), obj, PERL_MAGIC_tied, Nullch, 0);


Site Timeline