Jak mogę przekazać tablicę Perla przez odwołanie do modułu C XS?Jak mogę przekazać tablicę do funkcji C w Perlu XS?
my @array = (1..20);
XSTEST::test_array_passing(\@array);
Co mam zrobić w XS, aby zobaczyć tablicę?
Jak mogę przekazać tablicę Perla przez odwołanie do modułu C XS?Jak mogę przekazać tablicę do funkcji C w Perlu XS?
my @array = (1..20);
XSTEST::test_array_passing(\@array);
Co mam zrobić w XS, aby zobaczyć tablicę?
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.
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 */
}
}
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
Avinash: Możesz umieścić kod perlapi-using w dowolnych plikach c. Wystarczy dołączyć niezbędne nagłówki perl. – tsee
Należy również sprawdzić, czy odwołanie jest odwołaniem do tablicy. – tsee