为什么在XSUB中的输出变量上包括svsetmagic()



阅读perlxs文档,我来到OUTPUT关键字上的部分:

xsubpp 为所有参数发射自动SvSETMAGIC() XSUB的输出部分,除retval。这是通常想要的 行为,因为它会照顾适当地调用"集合"魔术的魔法 参数(需要用于哈希或数组元素参数必须为 如果它们不存在,则创建)。

我不确定我知道为什么需要set魔术(为什么RETVAL不需要它)?为什么需要set魔术和数组元素参数?

Perl的所有数据结构都支持魔术,而不仅仅是SV S(尽管名称),特别是Hashes and Arrays,这是tie机制或fieldhash之类的东西的基础在哈希条目级别上的弱参考的类似物。

由于OUTPUT指令指示XSUB的C主体可能会修改哪些参数,并且可能会传递一个可变的包含集合魔术的参数,因此根据TypeMap不调用设置处理程序的情况,设置值可能会导致行为不一致。。

use Scalar::Util qw(weaken);
my $foo;
my $ref = $foo;
weaken($ref);

作为魔术的示例,weaken降低了$foo的参考计数,并添加了将魔术指向$ref的魔术,以便当$foo收集垃圾时将其清除。

此外,它还为$ref添加了设定的魔术,拆除此反向引用,否则当$foo被销毁时,$ref即使此时不再指向$foo

如果您将$ ref用作参数,它会在堆栈上被别名(这就是$_[0]可分配的原因):

modifies_arguments($ref);
sub modifies_arguments {
    $_[0] = "blah"; # set magic is invoked to tear down the back referencing
} 

如果modifies_arguments是纯Perl,则很容易理解为什么这是合适的,但是关于正确性的相同假设当然必须保留XSUBS,这就是为什么OUTPUT用于标记哪些参数将其值设置为C的原因级别参数变量在功能主体的末尾具有,并设置了触发魔法。

这不适用于RETVAL,因为这不是技术上的作业,而是将新的SV推到堆栈上,并且在函数返回分配OP返回后,将处理任何集合魔法(如果有)。

这很简单。每当您分配给标量时,都需要在其上调用SvSETMAGIC(),以防它具有与之相关的魔术。

分配给RETVAL未分配给PERL变量,因此调用SvSETMAGIC(RETVAL)(除非您实际修改了RETVAL)是错误的。如果将返回的值分配给呼叫者中的另一个标量,则分配将在分配前的返回值上调用SvGETMAGIC,在分配后分配的变量上的SvSETMAGIC

相关内容

  • 没有找到相关文章

最新更新