in reply to simple XS

IV a = SvIV(SvRV(*res));

I think you don't want SvRV() here, as your *res already is an SV* holding a simple integer (returned by av_fetch()), which is what SvIV() wants.  In other words, AFAICT, *res doesn't hold an RV (a Perl reference), so no need to dereference it.

Replies are listed 'Best First'.
Re^2: simple XS
by spx2 (Deacon) on Mar 01, 2010 at 06:49 UTC
    ok I removed SvRV and I still get segfault

      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 :)