1

我需要使用 UDisks2 列出、过滤和打开块设备。我正在尝试列出所有可移动设备。

UDisks2 提供的GetBlockDevices方法a{sv}需要一个类型。如果我没记错的话,它是字符串键和 Variant 值的 HashTable。

如何使用此信息列出设备​​?到目前为止,我尝试了以下方法:

import std.stdio, ddbus;

void main()
{
    Connection conn = connectToBus();
    PathIface obj = new PathIface(conn, "org.freedesktop.UDsks2",
            "/org/freedesktop/UDisks2/Manager", "org.freedesktop.UDisks2.Manager");

    writeln(obj.call!string("GetBlockDevices", "org.freedesktop.DBus", ???));
}

call方法需要一个Argat 作为它的最后一个参数。我怎样才能a{sv}在那里提供?


我正在使用ddbus图书馆。


对于 args,我使用Variant!string[string]Variant 本身是一个模板类型。我还从调用方法参数中删除了多余的“org.freedesktop.DBus”。

import std.stdio, ddbus;
import ddbus: Variant;

void main()
{
    Connection conn = connectToBus();
    PathIface obj = new PathIface(conn, "org.freedesktop.DBus",
            "/org/freedesktop/UDisks2/Manager", "org.freedesktop.UDisks2.Manager");

    Variant!string[string] arg;
    writeln(obj.call!string("GetBlockDevices", arg));
}

但是我收到以下错误:

ddbus.exception.DBusException@../../.dub/packages/ddbus-2.3.0/ddbus/source/ddbus/thin.d(833):org.freedesktop.DBus 不理解消息 GetBlockDevices

4

1 回答 1

1

你的问题是:

  1. D-Bus 名称 org.freedesktop.UDisks2 在系统总线上(而不是在会话总线上),因此connectToBus()需要更改调用。
  2. 总线名称是org.freedeskop.UDisks2,而不是 org.freedesktop.DBus
  3. GetBlockDevices 的返回值是ao(对象路径数组),但您正在调用它,call!string这意味着您将返回一个字符串。将此更改为call!(ObjectPath[])
  4. (可选)你提出了你的论点Variant!string[string]。ddbus 中的Variant!T类型是一个帮助器,它只会使任何类型 T 像 dbus 协议中的变体一样,但它实际上不允许任何其他类型。如果你想支持传递 ddbus 支持 using 的任何类型,std.variant : Variant或者有一个特殊类型,你可以使用 ddbus 变体 usingVariant!DBusAny这是一个更轻量级的标记联合,仅支持所有 dbus 类型(以及更多内省)

我相信这段代码是你想要的,解决了所有问题:

import std.stdio, ddbus;
import ddbus : Variant;
import ddbus.c_lib;

void main()
{
    Connection conn = connectToBus(DBusBusType.DBUS_BUS_SYSTEM);
    PathIface obj = new PathIface(conn,
        busName("org.freedesktop.UDisks2"),
        ObjectPath("/org/freedesktop/UDisks2/Manager"),
        interfaceName("org.freedesktop.UDisks2.Manager"));

    Variant!DBusAny[string] arg;
    writeln(obj.call!(ObjectPath[])("GetBlockDevices", arg));
}

在这段代码中,我还使用了类型安全的 ddbus API,这使得 PathIface 中的参数更加清晰。类型安全 API 需要 ddbus 3.0.0-beta.1 或更高版本。

示例输出:

[/org/freedesktop/UDisks2/block_devices/sdc1, /org/freedesktop/UDisks2/block_devices/sdb1, /org/freedesktop/UDisks2/block_devices/sda, /org/freedesktop/UDisks2/block_devices/nvme0n1p2, /org/freedesktop/UDisks2/block_devices/sdb3, /org/freedesktop/UDisks2/block_devices/sdc, /org/freedesktop/UDisks2/block_devices/nvme0n1, /org/freedesktop/UDisks2/block_devices/sr0, /org/freedesktop/UDisks2/block_devices/nvme0n1p1, /org/freedesktop/UDisks2/block_devices/sde, /org/freedesktop/UDisks2/block_devices/sdb2, /org/freedesktop/UDisks2/block_devices/sdb, /org/freedesktop/UDisks2/block_devices/sda1, /org/freedesktop/UDisks2/block_devices/sde1, /org/freedesktop/UDisks2/block_devices/sdb4, /org/freedesktop/UDisks2/block_devices/sdd]
于 2020-08-25T14:17:52.773 回答