10

C XSモジュールを参照してPerl配列を渡すにはどうすればよいですか?

my @array = ( 1..20 );

XSTEST::test_array_passing(\@array);

配列を表示するためにXSで何をしますか?

4

2 に答える 2

11

AV*XSは、またはのいずれかとしてARRAYへの参照を受け取ることができますSV*。後者は、に逆参照する必要があり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);
}

このコードによって生成された.xsファイルは次のように宣言します。

double
sum_of_elements1 (array_ref)
        SV *    array_ref

double
sum_of_elements2 (array)
        AV *    array

編集:でsum_of_element2()、*SVが配列への参照であるというチェックを追加しました。

于 2009-10-01T17:36:40.087 に答える
8

Perl配列を渡して、たとえばintのC配列に自動的に変換することはできません。これを行うには、XSとperlapiに頼る必要があります。その理由は非常に単純です。perl配列には型指定されていないスカラーが含まれています。AC配列は、同じタイプのN個のアイテムを保持します。

あなたができることは、XSUBを取ることSV*です。SVスカラー値を表します。これには当然、参照(RV)が含まれるため、配列(AV's)への参照も含まれます。

SV*特定のソースが配列への参照であるかどうかを確認する方法は次のとおりです。

SV* tmpSV;
AV* theArray;
if (SvROK(source)) {                /* it's a reference */
  tmpSV = (SV*)SvRV(source);        /* deref */
  if (SvTYPE(tmpSV) == SVt_PVAV) {  /* it's an array reference */
    theArray = (AV*)tmpSV;
    /* do stuff with the array here */
  }
}
于 2009-10-01T17:46:28.937 に答える