【问题标题】:Passing pointer to pointer in Perl 6 NativeCall在 Perl 6 NativeCall 中将指针传递给指针
【发布时间】:2017-04-21 12:52:02
【问题描述】:

我正在尝试使用 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”应该强制 指向指针的指针,它应该以第一种方式工作。

我做错了什么?

【问题讨论】:

    标签: raku nativecall


    【解决方案1】:

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

    我知道的一种解决方法是仅使用指针大小的整数(特别是 size_tssize_t)作为 Perl6 端的参数和属性类型1,这应该可以按预期工作is rw

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

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


    1 如果你这样做,constant intptr = ssize_t 之类的定义将有助于提高可读性

    【讨论】:

    • 这对我有用。我刚刚停止使用 Pointer 并使用 size_t 并且 'is rw' 工作正常。
    【解决方案2】:

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

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2021-11-02
      • 1970-01-01
      • 1970-01-01
      • 2013-06-25
      • 1970-01-01
      • 2019-09-16
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多