2009-10-01 15 views

Odpowiedz

11

XS może otrzymać referencję do ARRAY jako AV* lub SV*. Ten ostatni musiałby zostać odesłany do 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); 
} 

Plik .xs produkowane przez ten kod deklaruje:

double 
sum_of_elements1 (array_ref) 
     SV * array_ref 

double 
sum_of_elements2 (array) 
     AV * array 

Edycja: w sum_of_element2(), dodał, że czek * SV było odniesienie do tablicy.

+0

Dzięki za odpowiedzi, będę próbować, ale w tym przypadku będę musiał dostarczyć operacje w pliku XS tylko, nie mogę umieścić operacji mojej macierzy w osobnym pliku C, ponieważ potrzebuję dostępu do struktury danych AV/SV tam – Avinash

+1

Avinash: Możesz umieścić kod perlapi-using w dowolnych plikach c. Wystarczy dołączyć niezbędne nagłówki perl. – tsee

+0

Należy również sprawdzić, czy odwołanie jest odwołaniem do tablicy. – tsee

8

Nie można przekazać tablicy Perla i jej automagicznie przekonwertować na, powiedzmy, tablicę C z ints. Będziesz musiał skorzystać z XS i perlapi, aby to zrobić. Powód jest dość prosty: tablica perl zawiera niesklasyfikowane skalary. Tablica C zawiera N elementów tego samego typu.

To, co możesz zrobić, to XSUB, która zajmuje SV*. SV oznacza wartość skalarną. To oczywiście zawiera odniesienia (RV), a więc także odniesienia do macierzy (AV).

Oto jak można sprawdzić, czy dana SV* źródłem jest odniesienie do tablicy:

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 */ 
    } 
} 
Powiązane problemy