Podsłówki Perl mogą zwracać (0 lub więcej) skalary. Gdy próbujesz zwrócić tablicę (niemożliwe bez awarii Perla!), Domyślna typemap zwróciła odwołanie do tej tablicy.
Zwróć uwagę, że twój program również wycieka z pamięci (ponieważ domyślna karta typów dla AV*
powinna umniejszyć twoją tablicę, ale jej nie).
Wracając odniesienie metoda 1
AV* /* Returns: sv_2mortal(newRV(RETVAL)) */
DoubleArray::getPerlArrayRef()
PREINIT:
size_t i;
CODE:
RETVAL = (AV*)sv_2mortal((SV*)newAV());
for (i=0; i < THIS->count; ++i) {
av_push(RETVAL, newSVnv(THIS->data[i]));
}
OUTPUT:
RETVAL
kontroli szczelności pamięci:
- Array RefCnt: 1 (
newAV
) -1 [opóźnione] (sv_2mortal
) + 1 (newRV
) = 1 [opóźniony] (własność b Y odniesienia)
- RefCnt referencyjnego: 1 (
newRV
) -1 [opóźnione] (sv_2mortal
) = 0 [opóźnione]
Perl
my $array = $C->getPerlArrayRef();
say for @$array;
Wracając odniesienie, metoda 2
SV* /* Returns: sv_2mortal(RETVAL) */
DoubleArray::getPerlArrayRef()
PREINIT:
AV* av;
size_t i;
CODE:
av = newAV();
RETVAL = newRV_noinc((SV*)av);
for (i=0; i < THIS->count; ++i) {
av_push(av, newSVnv(THIS->data[i]));
}
OUTPUT:
RETVAL
kontroli szczelności pamięci:
- RefCnt Array: 1 (
newAV
) +0 (newRV_noinc
) = 1 (własność przez odniesienie)
- referencyjnego RefCnt: 1 (
newRV_noinc
) -1 [opóźnione] (sv_2mortal
) = 0 [opóźnione]
Perl < jak wyżej>
Zwracanie referencji, metoda 3
void
DoubleArray::getPerlArrayRef()
PREINIT:
AV* av;
size_t i;
PPCODE:
av = newAV();
mXPUSHs(newRV_noinc((SV*)av));
for (i=0; i < THIS->count; ++i) {
av_push(av, newSVnv(THIS->data[i]));
}
sprawdzić wyciek pamięci:
- RefCnt Array: 1 (
newAV
) +0 (newRV_noinc
) = 1 (własność przez odniesienie)
- Podpunkt odniesienia: 1 (
newRV_noinc
) -1 [opóźniony] (mXPUSHs
) = 0 [opóźniony]
Perl: < samo jak powyżej>
Powracający skalary
musimy sprawdzić kontekst, ponieważ nie możemy miejsce więcej niż jeden skalar na stosie poza kontekstem listy.
void
DoubleArray::getElements()
PREINIT:
size_t i;
U8 gimme = GIMME_V;
PPCODE:
if (gimme == G_ARRAY) {
EXTEND(SP, THIS->count);
for (i=0; i < THIS->count; ++i) {
mPUSHn(THIS->data[i]);
}
}
else if (gimme == G_SCALAR) {
mXPUSHu(THIS->count);
}
Perl:
my $count = $C->getElements();
say $count;
my @array = $C->getElements();
say for @array;
Uwaga: RefCnt ubytek przez sv_2mortal
jest opóźnione aż rozmówca ma szansę zwiększa zawartość RefCnt.
https://www.nntp.perl.org/group/perl.xs/2011/06/msg2626.html wydaje się być odpowiedni – simbabque
@simbabque Widziałem już ten przykład wcześniej. To trochę bałagan. Trudno się uczyć. –
Czy mógłbyś podzielić się niektórymi rzeczami, których nauczyłeś się już ze społecznością? Możesz dodać rozdział lub dwa do https://github.com/xsawyerx/xs-fun. :-) – simbabque