Công cụ đăng ký Perl chỉ có thể trả về (0 hoặc nhiều hơn) vô hướng. Khi bạn cố gắng trả về một mảng (không thể không bị rơi Perl!), Typemap mặc định trả về một tham chiếu tới mảng đó.
Lưu ý rằng chương trình của bạn cũng bị rò rỉ bộ nhớ (vì typemap mặc định cho AV*
sẽ làm chết mảng của bạn nhưng không).
Trả về một tài liệu tham khảo, phương pháp 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
Memory rò rỉ séc:
- Array Avatar của refcnt: 1 (
newAV
) -1 [hoãn] (sv_2mortal
) + 1 (newRV
) = 1 [bị trễ] (thuộc sở hữu b y tham khảo)
- refcnt tham khảo của: 1 (
newRV
) -1 [hoãn] (sv_2mortal
) = 0 [hoãn]
Perl:
my $array = $C->getPerlArrayRef();
say for @$array;
Trở tham chiếu, phương pháp 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
Memory rò rỉ séc:
- Array Avatar của refcnt: 1 (
newAV
) +0 (newRV_noinc
) = 1 (thuộc sở hữu của tài liệu tham khảo)
- tham khảo của refcnt: 1 (
newRV_noinc
) -1 [hoãn] (sv_2mortal
) = 0 [hoãn]
Perl: < tương tự như trên>
Trả về một tài liệu tham khảo, phương pháp 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]));
}
Memory rò rỉ séc:
- refcnt Array Avatar của: 1 (
newAV
) +0 (newRV_noinc
) = 1 (thuộc sở hữu của tài liệu tham khảo)
- Tham chiếu của refcnt: 1 (
newRV_noinc
) -1 [bị trì hoãn] (mXPUSHs
) = 0 [hoãn]
Perl: < tương tự như trên>
vô hướng Trở
Chúng ta phải kiểm tra bối cảnh vì chúng ta không thể diễn ra nhiều hơn một vô hướng trên ngăn xếp bên ngoài ngữ cảnh danh sách.
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;
Lưu ý: Lượng giảm refcnt bởi sv_2mortal
bị trì hoãn cho đến khi người gọi có một cơ hội để tăng refcnt.
https://www.nntp.perl.org/group/perl.xs/2011/06/msg2626.html dường như có liên quan – simbabque
@simbabque Tôi đã xem ví dụ đó trước đây. Đó là một mớ hỗn độn. Khó học hỏi từ. –
Bạn có muốn chia sẻ một số điều bạn đã học được với cộng đồng không? Bạn có thể thêm một hoặc hai chương vào https://github.com/xsawyerx/xs-fun. :-) – simbabque