Тройной указатель родного вызова на Perl 6
Я пытаюсь обернуть SD-Bus с Perl6, но есть проблема с тройным указателем вызова функции.
с sd-bus.h
int sd_bus_list_names(sd_bus *bus, char ***acquired, char ***activatable); /* free the results */
попробуй с родным звонком
sub sd_bus_list_names(Pointer, Pointer[CArray[Str]] , Pointer[CArray[Str]] ) returns int32 is native('systemd') {*}
Я звоню, но я не знаю, как разыменовать массив (@) полученную и активируемую переменную.
спасибо и извините за мой английский
[РЕДАКТИРОВАТЬ]
dwarring ответ решить мою проблему с разыменования указатель [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);
1 ответ
У меня работает следующий автономный эксперимент:
Код C:
#include <stdio.h>
static char* strs[3] = { "howdy", "doody", NULL };
extern void ptr_to_strs (char ***ptr) {
*ptr = strs;
}
Код 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)
Используя этот подход (но не проверенный), вам нужно добавить 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