4

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

kmx
  • 7,912
  • 1
  • 15
  • 9

2 Answers2

5

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;
ikegami
  • 367,544
  • 15
  • 269
  • 518
  • @kmx, `MUTABLE_HV(sv)` is basically `(HV*)sv`, except it's safer since it'll issue an error for `const SV* const_sv; MUTABLE_HV(const_sv)`. – ikegami Apr 07 '11 at 06:09
  • just out of interest: where is this functionality documented? I googled for it, found this tread, but wanted do read the documentation about it also but "MUTABLE_HV" seems not to be documented in perldoc – user2875983 Oct 20 '14 at 06:32
  • It should be in perlapi, but it's not (though it's used in an example). There is a bit of documentation for them in the source where they are [defined](http://perl5.git.perl.org/perl.git/blob/572618de69892b6cdf7f9eacce39941a7d3d7ce5:/vutil.h#l8). – ikegami Oct 20 '14 at 13:46
1

If you are using "standard" objects, it is underlyingly just a hash, so you can use the HV methods. See e.g. http://perldoc.perl.org/perlguts.html#Working-with-HVs (actually, the whole perlguts page would be good reading for this...)

Your SV * to the object is a reference, so you can use SvRV to "dereference" it, casting it to an HV to pass to the hv_xxx functions (e.g. hv_fetch).

Best of luck!

jsegal
  • 1,281
  • 7
  • 6