>@_>@frame[0..4]>>main -e 1 XS::hello <<-6ren">
gpt4 book ai didi

perl - 如何模拟来自 XS 的 &sname 调用?

转载 作者:行者123 更新时间:2023-12-01 04:44:06 25 4
gpt4 key购买 nike

如何模拟 z XS 内的子行为子?

package XS;
sub hello {
print "ARGS: >>@_<<\n";
my $lvl;
while( my @frame = caller( $lvl++ ) ) {
print ">>@frame[0..4]<<\n";
}
}

sub z {
&hello;
}

在我的 .xs我有文件:
void
call_perl() {
call_pv( "XS::hello", G_NOARGS );
}

void
test(...)
CODE:
call_perl();

但是打电话 XS::test(1,2,3)不要将任何参数传递给 hello .

输出:
ARGS: >><<
>>main -e 1 XS::hello <<

在这里我们可以看到 $hasargs由于 G_NOARG 未设置标志标志,但为什么 @_脸红了吗?我错过了什么?

UPD
似乎找到了一半的答案。
  • G_NOARGS旗帜

    has the effect of not creating the @_ array for the Perl subroutine.

  • XSUB被称为 perl 不要为它创建框架(不记得这是在哪里描述的)并且不要填充 @_对于它(这描述了 间接 here)

    XSUBs refer to their stack arguments with the macro ST(x)


  • 所以更准确的问题是:

    如何传播XSUB堆栈参数 PP子程序?

    注意:我不能只使用:
    call_pv( "XS::hello", 0 );

    因为这是顺序PP子调用。当它返回 XSUB 时堆栈参数将替换为来自 XS::hello 的返回值子
    int count =  call_pv( "XS::hello", 0 );
    STAGAIN;
    printf( "%s\n", SvPV_nolen( ST(0) ) );

    所以我供应 G_NOARGS标志能够访问 XSUB调用后的堆栈参数 PP

    最佳答案

    这是 XSUB 的代码它是如何完成的(注意:在这个例子中我不处理返回参数):

    test(...)
    CODE:
    AV *defav_old = GvAV(PL_defgv); # Save current @_

    AV *av = newAV(); # Create new array
    av_extend(av, items -1);
    AvREIFY_only(av);
    AvFILLp(av) = items -1;
    Copy(MARK+1, AvARRAY(av), items, SV*); # Fill array by elements from stack

    GvAV(PL_defgv) = av; # point @_ to our new array


    PUSHMARK(SP);
    int count = call_pv( "XS::Utils::hello", G_VOID | G_NOARGS );

    GvAV(PL_defgv) = defav_old; # Restore old @_

    关于perl - 如何模拟来自 XS 的 &sname 调用?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/48350260/

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