2009-10-01 1 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 파일에 작업을 제공해야합니다 오직, 나는 AV/SV 자료 구조 접근을 필요로 할 것이므로 배열 작업을 별도의 C 파일에 둘 수는 없다. – Avinash

+1

Avinash : perlapi를 사용하는 코드를 임의의 c 파일에 넣을 수있다. 꼭 필요한 perl 헤더를 포함하십시오. – tsee

+0

또한 참조가 배열에 대한 참조인지 확인해야합니다. – tsee

8

Perl 배열을 전달할 수없고 자동으로 C 배열 (예 : int 배열)로 변환 할 수 없습니다. XS와 perlapi에 의존해야합니다. 이유는 아주 간단합니다. 펄 배열은 타입이없는 스칼라를 포함합니다. C 배열은 동일한 유형의 N 개 항목을 보유합니다.

XSUB에 수행 할 수있는 작업은 SV*입니다. SV은 스칼라 값의 약자입니다. 이것은 당연히 참고 문헌 (RV)을 포함하며 따라서 배열 (AV ')에 대한 참조도 포함합니다. 여기

은 주어진 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 */ 
    } 
}