我正在尝试使用NativeCall与某些C函数进行交互.
对于一种情况,我需要传入由函数更新的指针,因此它需要指向指针的指针'void**'.
我试过这样的:
class Foo
{
has Pointer $.first;
has Pointer $.last;
sub somefunc(Pointer is rw, Pointer is rw, Str) is native { * }
method myfunc(Str $arg) {
somefunc($!first, $!last, $arg);
}
}
Run Code Online (Sandbox Code Playgroud)
它不起作用.指针不会被函数更新.
由于C数组基本上是指向指针的指针,我可以这样伪造它:
class Foo
{
has Pointer $.first;
has Pointer $.last;
sub somefunc(CArray[Pointer], CArray[Pointer], Str) is native { * }
method myfunc(Str $arg) {
my $first = CArray[Pointer].new($!first);
my $last = CArray[Pointer].new($!last);
somefunc($first, $last, $arg);
$!first = $first[0];
$!last = $last[0];
}
}
Run Code Online (Sandbox Code Playgroud)
它工作得很好.看起来像"是rw"应该强制指针指针,它应该以第一种方式工作.
我究竟做错了什么?
最后我检查了一下,NativeCall仍然有一些粗糙的边缘,有时需要一点创造力;这可能是其中之一。
我知道的一种解决方法是仅使用指针大小的整数(特别是size_t或ssize_t)作为 Perl6 一侧的参数和属性类型1,这应该按预期与 一起工作is rw。
整数和指针之间的转换很容易:使用 prefix +,.Int甚至只需分配给整数类型变量即可转换为整数,或者Pointer.new(\xe2\x80\xa6)用于nqp::box_i(\xe2\x80\xa6, Pointer)另一个方向。
如果需要,可以使用访问器方法来自动执行此转换。
\n\n1如果你这样做,这样的定义constant intptr = ssize_t将有助于可读性