阅读perlxs文档,我来到了OUTPUT
关键字的部分:
xsubpp
SvSETMAGIC()
为XSUB的OUTPUT部分中的所有参数发出自动,RETVAL除外.这是通常需要的行为,因为它负责在输出参数上正确调用'set'魔术(如果它们不存在则必须创建的哈希或数组元素参数需要).
我不确定我理解为什么需要set
魔法(以及为什么不需要魔法RETVAL
)?为什么set
哈希和数组元素参数需要魔术?
所有Perl的数据结构都支持魔术,而不仅仅是SV
s(尽管名称),特别是对于哈希和数组,这是诸如在哈希条目级别实现弱引用模拟的tie
机制或类似事物的基础fieldhash
.
由于该OUTPUT
指令指示哪些参数可能会被XSUB的C主体修改,并且可能传入包含set magic的变量,因此根据typemap设置该值而不调用set handler可能会导致行为不一致.
use Scalar::Util qw(weaken);
my $foo;
my $ref = \$foo;
weaken($ref);
Run Code Online (Sandbox Code Playgroud)
作为魔法的一个例子,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
}
Run Code Online (Sandbox Code Playgroud)
如果modifies_arguments
是一个纯粹的Perl,很容易理解为什么这是合适的,但是关于正确性的相同假设当然必须适用于XSUB,这就是为什么OUTPUT
用于标记哪些参数的值设置为C级参数变量所具有的值.函数体的结束,并设置了魔法触发.
这不适用于RETVAL
,因为这在技术上不是一个赋值,而是将一个新的SV推入堆栈,并且在函数返回赋值操作(如果有的话)之后将处理任何设置魔法.