Come posso passare l'array Perl facendo riferimento al modulo C XS?Come posso passare un array a una funzione C in Perl XS?
my @array = (1..20);
XSTEST::test_array_passing(\@array);
Cosa faccio in XS in modo che veda la matrice?
Come posso passare l'array Perl facendo riferimento al modulo C XS?Come posso passare un array a una funzione C in Perl XS?
my @array = (1..20);
XSTEST::test_array_passing(\@array);
Cosa faccio in XS in modo che veda la matrice?
XS può ricevere un ARRAY come AR o AV*
o SV*
. Quest'ultimo dovrebbe essere sottoposto a dereferenziazione a 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);
}
Il file .xs prodotta da questo codice dichiara:
double
sum_of_elements1 (array_ref)
SV * array_ref
double
sum_of_elements2 (array)
AV * array
Edit: in sum_of_element2()
, ha aggiunto il controllo che il * SV era un riferimento ad un array.
Non è possibile passare un array Perl e convertirlo automaticamente, ad esempio, in un array C di ints. Dovrai ricorrere a XS e allo perlapi per farlo. La ragione è piuttosto semplice: un array perl contiene scalari non tipizzati. Un array C contiene N elementi dello stesso tipo.
Quello che puoi fare è avere un XSUB
che prende uno SV*
. SV
indica il valore scalare. Ciò include naturalmente i riferimenti (RV
) e quindi anche i riferimenti agli array (AV
).
Ecco come è possibile verificare se un determinato SV*
fonte è un riferimento ad un array:
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 */
}
}
Grazie per la risposta, cercherò questo, ma in questo caso ho dovranno fornire le operazioni nel file XS solo, non posso mettere le operazioni dell'array in un file C separato, poiché avrò bisogno dell'accesso alla struttura dati AV/SV lì – Avinash
Avinash: Puoi inserire il codice perlapi-using in file c arbitrari. Basta includere le intestazioni perl necessarie. – tsee
Si desidera anche verificare se il riferimento è un riferimento a un array. – tsee