perlxs

Accessing value stored in a perl object (blessed hash) from XS


I have a perl object (blessed reference to hash) like this.

sub funcname {
  #some code
}

my $o = My::Class->new();
$o->{internal_data} = \&funcname; #I know it is not nice

At other place somewhere in XS code where I have $o reference I need to get the value of $o->{internal_data}.

/* at some point in XS code */
SV *obj = ... /* $o value passed to a XS function */
SV *func;
...
/* here I do not know how to load $o->{internal_data} value into func */
...
call_sv(func,G_SCALAR);

There is perhaps some chapter in perl(api|xstut|guts|???). I just was not able to find it.

Thanks in advance for any hint.

-- kmx


Solution

  • SvRV will get you the hash (as an SV*) from the reference, MUTABLE_HV will cast it to a an HV*, hv_fetch/hv_fetchs will fetch from the hash.

    SV*  self;
    SV*  obj_sv;
    HV*  obj_hv;
    SV** callback_ptr;
    SV*  callback;
    
    self = ...;
    SvGETMAGIC(self);
    if (!SvROK(self))
        croak("Not a reference");
    
    obj_sv = SvRV(self);
    if (SvTYPE(obj_sv) != SVt_PVHV)
        croak("Not a reference to a hash");
    
    obj_hv = MUTABLE_HV(obj_sv);
    
    callback_ptr = hv_fetchs(obj_hv, "internal_data", 0);
    if (!callback_ptr)
        croak("Malformed object");
    
    callback = *callback_ptr;