in reply to Re: simple XS
in thread simple XS

ok I removed SvRV and I still get segfault

Replies are listed 'Best First'.
Re^3: simple XS
by almut (Canon) on Mar 01, 2010 at 08:01 UTC

    Taking a closer look, I think there are also other problems with your code. In particular, you're not (Perl-)dereferencing (SvRV()) the arrayref you get from hv_fetch() as the value associated with the hash entry "permutation". Also, you're not checking that the SV** pointer which hv_fetch() returns is non-null before (C-)dereferencing it...

    Somewhat simplified, the sequence of steps should look something like this (I'm using Inline::C here for ease of demo):

    #!/usr/bin/perl -l use Inline C => <<'EOC'; int get(SV* self, int index) { HV* h = (HV*) SvRV(self); char* key = "permutation"; SV** aref = hv_fetch(h, key, strlen(key), FALSE); if (aref == NULL) { /* ... */ exit(-1); } AV* a = (AV*) SvRV(*aref); SV** res = av_fetch(a, index, FALSE); if (res == NULL) { /* ... */ exit(-1); } IV i = SvIV(*res); return i; } EOC my $obj = bless { permutation => [2,42,2,2,2,2,2,2,2,2,2] }, "Whatever +"; print get($obj, 1); # prints 42

    In real (production) code, you should also verify that you in fact have the appropriate types (using SvROK(), SvIOK(), etc.) before treating them as such.

    (As for chromatic's note below, the mapping of the Perl integer to the C int index is being taken care of by Inline::C in this example.)

      In real (production) code, you should also verify that you in fact have the appropriate types (using SvROK(), SvIOK(), etc.) before treating them as such

      Yes, SvROK(*aref) should be checked, but checking SvIOK(*res) is not required because SvIV coerces.

      #!/usr/bin/perl use Inline C => <<'EOC'; void show(SV* index) { PerlIO_printf(PerlIO_stdout(), "%d\n", SvIOK(index)); PerlIO_printf(PerlIO_stdout(), "%d\n", SvIV(index)); } EOC show("123456");
      0 123456
      thanks, through your suggestion I was able to fix my code :)