perl 6上的三指针本机调用

vbe*_*eme 7 perl6 nativecall

我尝试用perl6包装sd-bus,但是函数调用三指针有问题.
来自sd-bus.h

int sd_bus_list_names(sd_bus *bus, char ***acquired, char ***activatable); /* free the results */
Run Code Online (Sandbox Code Playgroud)

尝试原生呼叫

sub sd_bus_list_names(Pointer, Pointer[CArray[Str]] , Pointer[CArray[Str]] ) returns int32 is native('systemd') {*}
Run Code Online (Sandbox Code Playgroud)

我打电话,但我不知道如何对数组(@)获取和激活变量的dereferencies.

谢谢,对不起我的英语

[ 编辑 ]
侏儒回复解决我的问题derefencies指针[CArray [Str]]

这是一个测试代码:

use v6;
use NativeCall;
sub strerror(int32) returns Str is native {*}
sub sd_bus_default_system(Pointer is rw) returns int32 is native('systemd') {*}
sub sd_bus_unref(Pointer) returns Pointer is native('systemd') {*}
sub sd_bus_list_names(Pointer,Pointer[CArray[Str]] is rw, Pointer[CArray[Str]] is rw ) returns int32 is native('systemd') {*}

my Pointer $bus .= new;
my int32 $error;

$error=sd_bus_default_system($bus);
if $error < 0 {
    my Str $ser = strerror(-$error);
    die "fail, can't test triple pointer, dbus return error $error $ser";
}

my Pointer[CArray[Str]] $acq .= new;
my Pointer[CArray[Str]] $act .= new;
$error=sd_bus_list_names($bus,$acq,$act);

my @love6acq;
loop (my $i = 0; $acq.deref[$i]; $i++){
    @love6acq.push: $acq.deref[$i];
}
@love6acq.say;

my @love6act;
loop (my $i = 0; $act.deref[$i]; $i++){
    @love6act.push: $act.deref[$i];
}
@love6act.say;

sd_bus_unref($bus);
Run Code Online (Sandbox Code Playgroud)

dwa*_*ing 8

以下独立实验对我有用:

C代码:

#include <stdio.h>
static char* strs[3] = { "howdy", "doody", NULL };
extern void ptr_to_strs (char ***ptr) {
  *ptr = strs;
}
Run Code Online (Sandbox Code Playgroud)

Perl代码:

use v6;
use LibraryMake;
use NativeCall;

sub testlib {
    state $ = do {
    my $so = get-vars('')<SO>;
    ~(%?RESOURCES{"lib/test$so"});
    }
}

sub ptr_to_strs(Pointer[CArray[Str]] $strs is rw) is native(&testlib)

my Pointer[CArray[Str]] $a .= new;
ptr_to_strs($a);
say $a.deref[0]; # howdy
say $a.deref[1]; # doody
say $a.deref[2]; # (Str)
Run Code Online (Sandbox Code Playgroud)

使用这种方法(但未经测试),您需要添加is rw到签名并在调用之前创建指针:

# assuming you've already got a $bus object
sub sd_bus_list_names(Pointer, Pointer[CArray[Str]] is rw, Pointer[CArray[Str]] is rw) returns int32 is native('systemd') {*}

my Pointer[CArray[Str]] $acq .= new;
my Pointer[CArray[Str]] $act .= new;
sd_bus_list_names($bus, $acq, $act);
say $acq.deref[0]; # first acquired name
Run Code Online (Sandbox Code Playgroud)

  • @jjmerelo LibraryMake也是构建过程的一部分.我已将此问题的工作方式发布到https://github.com/dwarring/nativecall-demo-p6.希望在LibraryMake之后运行并运行Build.pm它应该是好的. (2认同)