Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How can I pass an array to a C function in Perl XS?

Tags:

perl

xs

How can I pass Perl array by reference to C XS module?

my @array = ( 1..20 );

XSTEST::test_array_passing(\@array);

What do I do in XS so it sees the array?

like image 807
Avinash Avatar asked Oct 01 '09 12:10

Avinash


1 Answers

XS can receive a ref to ARRAY as either an AV* or an SV*. The latter would have to be dereferenced to an AV*.

use Inline C => DATA;
@array = (1 .. 20);
$r = sum_of_elements1(\@array);
$s = sum_of_elements2(\@array);
print "$r $s\n";  #  produces output: "210 210\n"
__END__
__C__
double sum_of_elements1(AV* array)
{
  int i;
  double sum = 0.0;
  for (i=0; i<=av_len(array); i++) {
    SV** elem = av_fetch(array, i, 0);
    if (elem != NULL)
      sum += SvNV(*elem);
  }
  return sum;
}

double sum_of_elements2(SV* array_ref)
{
  AV* array;
  if (!SvROK(array_ref) || SvTYPE(SvRV(array_ref)) != SVt_PVAV)
    croak("expected ARRAY ref");
  array = (AV*) SvRV(array_ref);
  return sum_of_elements1(array);
}

The .xs file produced by this code declares:

double
sum_of_elements1 (array_ref)
        SV *    array_ref

double
sum_of_elements2 (array)
        AV *    array

Edit: in sum_of_element2(), added the check that the *SV was a reference to an array.

like image 63
mob Avatar answered Nov 01 '22 19:11

mob