阅读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
。