OlegG has asked for the wisdom of the Perl Monks concerning the following question:

Hi, I am newbie in XS.
Perl code:
my ($num, $str); sub_from_xs(\$num, \$str);
XS:
void sub_from_xs(SV *num, SV *str) INIT: if ((!SvROK(num))) croak("not a reference"); if ((!SvROK(str))) croak("not a reference"); int nx; char *sx; CODE: nx = get_nx(); sv_setiv_mg(SvRV(num), nx); sx = get_sx(); sv_setpv_mg(SvRV(str), sx);
Is this code correct? How to assign new values to passed references properly?

Replies are listed 'Best First'.
Re: XSUB: pass scalar by reference and assign value
by ikegami (Patriarch) on Jun 13, 2011 at 20:54 UTC

    Yes. It does all the steps:

    1. Upgrades the scalar to something that can hold the desired type if it can't already.
    2. Sets the value in the appropriate field of scalar.
    3. Sets the bit indicating the appropriate field of the scalar has data, clearing the bits for the other fields.
    4. Calls the scalar's set magic handler, if there is one.
      Thanks ikegami.
      It was segfault with my XS code. So, I thought, that I do incorrect assigment to reference. But as usual problem was in the other place.
Re: XSUB: pass scalar by reference and assign value
by ikegami (Patriarch) on Jun 14, 2011 at 04:11 UTC

    By the way, you don't need to pass references.

    sub_from_xs(my $num, my $str);
    void sub_from_xs(SV *num, SV *str) PREINIT: int nx; char *sx; CODE: nx = get_nx(); sx = get_sx(); sv_setiv_mg(num, nx); sv_setpv_mg(str, sx);

    But I would personally prefer to see this function return a two element list.

    my ($num, $str) = sub_from_xs();
    void sub_from_xs() PREINIT: int nx; char *sx; PPCODE: nx = get_nx(); sx = get_sx(); EXTEND(SP, 2); PUSHs(sv_2mortal(newSViv(nx))); PUSHs(sv_2mortal(newSVpv(sx, 0)));