如何通過引用C XS模塊傳遞Perl數組?如何將數組傳遞給Perl XS中的C函數?
my @array = (1..20);
XSTEST::test_array_passing(\@array);
在XS中做什麼,它看到數組?
如何通過引用C XS模塊傳遞Perl數組?如何將數組傳遞給Perl XS中的C函數?
my @array = (1..20);
XSTEST::test_array_passing(\@array);
在XS中做什麼,它看到數組?
XS可以接收ARRAY的參考號爲AV*
或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是一個數組的引用。
您無法傳遞Perl數組並將其自動轉換爲C數組。你將不得不求助於XS和perlapi來做到這一點。原因很簡單:perl數組包含無類型標量。 C數組包含相同類型的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 */
}
}
感謝答案,我會嘗試這一點,但在這種情況下,我將不得不在XS文件提供操作只是,我不能把我的數組操作放在單獨的C文件中,因爲我需要AV/SV數據結構訪問 – Avinash 2009-10-01 17:43:45
Avinash:您可以將perlapi使用代碼放在任意c文件中。只需包含必需的perl頭文件。 – tsee 2009-10-01 17:48:06
您還想檢查引用是否是對數組的引用。 – tsee 2009-10-01 17:48:40