You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Perl 6封装sd-bus时三重指针函数调用与解引用问题

Perl 6 封装 sd-bus:三重指针函数的调用与解引用方案

问题背景

我尝试用Perl 6的NativeCall封装systemd的sd-bus库,但在调用带有三重指针的sd_bus_list_names函数时遇到了麻烦——调用后不知道怎么把返回的acquired和activatable变量解引用成Perl 6的数组。

原C函数定义(来自sd-bus.h)

int sd_bus_list_names(sd_bus *bus, char ***acquired, char ***activatable); /* free the results */

最初的NativeCall尝试

我一开始是这么定义函数的,但解引用的时候完全摸不着头绪:

sub sd_bus_list_names(Pointer, Pointer[CArray[Str]] , Pointer[CArray[Str]] ) returns int32 is native('systemd') {*}

解决后的完整测试代码

感谢dwarring的回复,终于搞定了解引用的问题,以下是可运行的测试代码:

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);

# 将 acquired 转换为 Perl 6 数组
my @love6acq;
loop (my $i = 0; $acq.deref[$i]; $i++){
    @love6acq.push: $acq.deref[$i];
}
@love6acq.say;

# 将 activatable 转换为 Perl 6 数组
my @love6act;
loop (my $i = 0; $act.deref[$i]; $i++){
    @love6act.push: $act.deref[$i];
}
@love6act.say;

sd_bus_unref($bus);

关键要点说明

  1. 修正NativeCall函数声明:给Pointer[CArray[Str]]参数加上is rw,因为C函数会把分配好的字符串数组的地址写入你传入的指针变量中,必须允许函数修改这些指针的值。
  2. 解引用逻辑:通过$acq.deref拿到底层的CArray[Str],然后循环遍历数组元素直到遇到空字符串(C风格的字符串数组结束标记),把每个元素添加到Perl 6数组里。
  3. 资源释放:记得调用sd_bus_unref释放总线句柄,避免内存泄漏(另外注意C函数注释里提到需要free返回的结果,实际使用时别忘了添加对应的内存释放逻辑)。

内容的提问来源于stack exchange,提问作者vbextreme vbextreme

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.29 07:10:54