2017-04-21 100 views
3

我试图使用Nativecall与一些C函数进行交互。将指针传递给Perl 6 Nativecall

对于一种情况,我需要传入由 函数更新的指针,所以它需要一个指向'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]; 
    } 
} 

它正常工作,是这样的。它看起来像“是rw”应该强制指向指针,它应该以第一种方式工作。

我在做什么错?

回答

3

最后我检查了一下,NativeCall仍然有一些粗糙的边缘,有时需要一点创意;这可能是其中的一种情况。

一个解决方法我知道的是只使用指针大小整数(即,size_tssize_t)作为参数和属性对Perl6侧类型,应该工作与is rw预期。

这很容易整数和指针之间的转换:使用前缀+.Int甚至只是分配到一个整数类型的变量转换为整数,Pointer.new(…)nqp::box_i(…, Pointer)的另一个方向。

如果需要,可以使用访问器方法来自动执行此转换。


如果你走这条路,定义如constant intptr = ssize_t将有助于可读性

+1

这对我的作品。我刚刚停止使用指针,并使用size_t和'是RW'工作正常。 –

1

这在版本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;