arrays – perl xs – 从c数组返回perl数组
使用XS我试图将值从C数组传递到可以在脚本中使用的Perl数组.
这是我的xs文件中的代码: AV * DoubleArray::getPerlArray() CODE: r = newAV(); for(size_t i=0; i < THIS->count; i++) { av_push(RETVAL,newSVnv(THIS->data[i])); } OUTPUT: RETVAL 它编译得很好但是当我在perl中运行以下代码时: my @d = $C->getPerlArray(); foreach(@d) { print "$_n"; } 当我希望它打印一个数字列表时,它只打印ARRAY(0x1408cdc). 如何修改我的代码以正确传回perl数组? 解决方法
Perl subs只能返回(0或更多)标量.当您尝试返回一个数组时(不可能崩溃Perl!),默认的typemap会返回对该数组的引用.
请注意,您的程序也会泄漏内存(因为AV *的默认类型映射应该会使您的阵列死亡,但不会). 返回参考,方法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 内存泄漏检查: >数组的refcnt:1(newAV)-1 [延迟](sv_2mortal)1(newRV)= 1 [延迟](由参考所有) Perl的: my $array = $C->getPerlArrayRef(); say for @$array; 返回参考,方法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 内存泄漏检查: >数组的refcnt:1(newAV)0(newRV_noinc)= 1(由引用拥有) Perl:<与上面相同> 返回参考,方法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])); } 内存泄漏检查: >数组的refcnt:1(newAV)0(newRV_noinc)= 1(由引用拥有) Perl:<与上面相同> 返回标量 我们必须检查上下文,因为我们不能在列表上下文之外的堆栈上放置多个标量. 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; 注意:sv_2mortal的refcnt减少会延迟,直到调用者有机会增加refcnt. (编辑:李大同) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |