Доступ к значению, хранящемуся в объекте perl (благословенный хеш) из XS - PullRequest
4 голосов
/ 07 апреля 2011

У меня есть объект perl (благословенная ссылка на хеш), подобный этому.

sub funcname {
  #some code
}

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

В другом месте где-нибудь в коде XS, где у меня есть ссылка на $ o, мне нужно получить значение $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);

Возможно, в Perl есть какая-то глава (api | xstut | guts | ???).Я просто не смог его найти.

Заранее спасибо за любой намек.

- kmx

Ответы [ 2 ]

5 голосов
/ 07 апреля 2011

SvRV получит хеш (как SV*) из ссылки, MUTABLE_HV приведёт его к HV*, hv_fetch / hv_fetchs получит из хеша.

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;
1 голос
/ 07 апреля 2011

Если вы используете «стандартные» объекты, это просто хеш, поэтому вы можете использовать методы HV. Смотрите, например http://perldoc.perl.org/perlguts.html#Working-with-HVs (на самом деле, вся страница perlguts была бы хороша для этого ...)

Ваш SV * к объекту является ссылкой, поэтому вы можете использовать SvRV для «разыменования» его, приведя его к HV для передачи в функции hv_xxx (например, hv_fetch).

Удачи!

...