2009-10-01 37 views

Trả lời

11

XS có thể nhận được tham chiếu đến ARRAY là AV* hoặc SV*. Sau này sẽ phải được dereferenced một 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); 
} 

File .xs sản xuất bởi mã này tuyên bố:

double 
sum_of_elements1 (array_ref) 
     SV * array_ref 

double 
sum_of_elements2 (array) 
     AV * array 

Edit: trong sum_of_element2(), bổ sung việc kiểm tra rằng * SV là một tham chiếu đến một mảng.

+0

Cảm ơn cho câu trả lời, tôi sẽ cố gắng này, Nhưng trong trường hợp này tôi sẽ phải cung cấp các hoạt động trong file XS chỉ, tôi không thể đặt các hoạt động mảng của mình trong tệp C riêng biệt, vì tôi sẽ cần truy cập cấu trúc dữ liệu AV/SV ở đó – Avinash

+1

Avinash: Bạn có thể đặt mã perlapi-sử dụng trong các tệp c tùy ý. Chỉ cần bao gồm các tiêu đề perl necesary. – tsee

+0

Bạn cũng muốn kiểm tra xem tham chiếu có phải là tham chiếu đến một mảng hay không. – tsee

8

Bạn không thể chuyển mảng Perl và tự động chuyển đổi thành mảng C, ví dụ: Bạn sẽ phải sử dụng XS và perlapi để thực hiện việc này. Lý do khá đơn giản: một mảng perl chứa vô hướng vô hướng. Một mảng C chứa N mục cùng loại.

Những gì bạn có thể làm là có XSUB mất SV*. SV là viết tắt của giá trị vô hướng. Điều này tự nhiên bao gồm tài liệu tham khảo (RV) và do đó cũng tham chiếu đến mảng (AV 's).

Đây là cách bạn có thể kiểm tra xem một SV* nguồn nhất định là một tham chiếu đến một mảng:

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 */ 
    } 
} 
Các vấn đề liên quan