gpt4 book ai didi

arrays - perl xs-从c数组返回perl数组

转载 作者:行者123 更新时间:2023-12-04 06:53:55 24 4
gpt4 key购买 nike

我试图使用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订阅只能返回(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

内存泄漏检查:
  • 数组的引用:1(newAV)-1 [delayed](sv_2mortal)+1(newRV)= 1 [delayed](由引用拥有)
  • 引用的引用:1(newRV)-1 [delayed](sv_2mortal)= 0 [delayed]

  • 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

    内存泄漏检查:
  • 数组的引用:1(newAV)+0(newRV_noinc)= 1(引用拥有)
  • 引用的引用:1(newRV_noinc)-1 [delayed](sv_2mortal)= 0 [delayed]

  • 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]));
    }

    内存泄漏检查:
  • 数组的引用:1(newAV)+0(newRV_noinc)= 1(引用拥有)
  • 引用的引用:1(newRV_noinc)-1 [delayed](mXPUSHs)= 0 [delayed]

  • 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。

    关于arrays - perl xs-从c数组返回perl数组,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/46719061/

    24 4 0
    Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
    广告合作:1813099741@qq.com 6ren.com