将指针传递给 Perl 6 NativeCall 中的指针
Passing pointer to pointer in Perl 6 NativeCall
我正在尝试使用 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);
}
}
没用。函数不会更新指针。
因为 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];
}
}
像这样效果很好。看起来 "is rw" 应该强制
指向指针的指针,它应该以第一种方式工作。
我做错了什么?
最后我检查了一下,NativeCall
仍然有一些粗糙的边缘,有时需要一点创造力;这可能是其中一种情况。
我知道的一个解决方法是只使用指针大小的整数(具体来说,size_t
或 ssize_t
)作为 Perl6 端的参数和属性类型1,它应该按预期工作 is rw
。
整数和指针之间的转换很容易:使用前缀 +
、.Int
甚至只是赋值给整数类型的变量以转换为整数,以及 Pointer.new(…)
或 nqp::box_i(…, Pointer)
换个方向。
如果需要,访问器方法可用于自动执行此转换。
1 如果您这样做,constant intptr = ssize_t
之类的定义将有助于提高可读性
这适用于我的 2017.09 版本:
class Pdu is repr('CStruct') { ... }
sub snmp_synch_response(Snmp-session, Pdu, Pointer[Pdu] is rw) returns int32 is native("netsnmp") { * };
my $p = Pointer[Pdu].new;
my $status = snmp_synch_response($ss, $pdu, $p);
say $status, "-", $p;
my $resp = $p.deref;
say $resp;
我正在尝试使用 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);
}
}
没用。函数不会更新指针。
因为 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];
}
}
像这样效果很好。看起来 "is rw" 应该强制 指向指针的指针,它应该以第一种方式工作。
我做错了什么?
最后我检查了一下,NativeCall
仍然有一些粗糙的边缘,有时需要一点创造力;这可能是其中一种情况。
我知道的一个解决方法是只使用指针大小的整数(具体来说,size_t
或 ssize_t
)作为 Perl6 端的参数和属性类型1,它应该按预期工作 is rw
。
整数和指针之间的转换很容易:使用前缀 +
、.Int
甚至只是赋值给整数类型的变量以转换为整数,以及 Pointer.new(…)
或 nqp::box_i(…, Pointer)
换个方向。
如果需要,访问器方法可用于自动执行此转换。
1 如果您这样做,constant intptr = ssize_t
之类的定义将有助于提高可读性
这适用于我的 2017.09 版本:
class Pdu is repr('CStruct') { ... }
sub snmp_synch_response(Snmp-session, Pdu, Pointer[Pdu] is rw) returns int32 is native("netsnmp") { * };
my $p = Pointer[Pdu].new;
my $status = snmp_synch_response($ss, $pdu, $p);
say $status, "-", $p;
my $resp = $p.deref;
say $resp;