2009-10-01 69 views

回答

11

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是一個數組的引用。

+0

感謝答案,我會嘗試這一點,但在這種情況下,我將不得不在XS文件提供操作只是,我不能把我的數組操作放在單獨的C文件中,因爲我需要AV/SV數據結構訪問 – Avinash 2009-10-01 17:43:45

+1

Avinash:您可以將perlapi使用代碼放在任意c文件中。只需包含必需的perl頭文件。 – tsee 2009-10-01 17:48:06

+0

您還想檢查引用是否是對數組的引用。 – tsee 2009-10-01 17:48:40

8

您無法傳遞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 */ 
    } 
}