D-Bus,UDisks和Glibmm的绑定

时间:2012-01-23 19:31:48

标签: linux glib dbus variant

我遇到了一个简单的D-Bus概念问题。我正在使用Glibmm D-Bus绑定(Gio :: DBus命名空间)来访问UDisks接口。我想读一下系统上找到的每个硬盘的一些属性,所以首先我需要枚举UDisks报告的所有磁盘,如下所示:

Glib::RefPtr<Gio::DBus::Connection> bus;

int main() {
    using namespace Glib;
    using namespace Gio;

    Glib::init();
    Gio::init();

    bus = DBus::Connection::get_sync(Gio::DBus::BUS_TYPE_SYSTEM);
    RefPtr<DBus::Proxy> udisks_proxy = DBus::Proxy::create_sync(bus, "org.freedesktop.UDisks", "/org/freedesktop/UDisks", "org.freedesktop.UDisks");

    VariantContainerBase devices_variant = udisks_proxy->call_sync("EnumerateDevices");
    VariantIter iterator(devices_variant.get_child(0));

    Variant<ustring> var;
    while(iterator.next_value(var)) {
        ustring name = var.get();

        LOG("device: '%s", name.c_str());
        process_device(name);
    }

    return 0;
}

这似乎工作正常,因为call_sync()返回VariantContainerBase,它保存(ao)对象,基本上是:“对象路径数组的一个结构”。从文档中我读到“对象路径”类型的处理方式与“字符串”类型相同,这就是为什么在VariantBase期间创建的无类型get_child(0)允许自己被转换为{ {1}}对象。使用此参数化Variant,使用Variant<ustring>提取字符串非常简单。

但是我正在尝试使用此方法从每个驱动器的属性中读取一些内容(在本例中为var.get()属性):

NativePath

问题是void process_device(const Glib::ustring& objpath) { using namespace Glib; using namespace Gio; RefPtr<DBus::Proxy> attrs = DBus::Proxy::create_sync(bus, "org.freedesktop.UDisks", objpath, "org.freedesktop.DBus.Properties"); std::vector<VariantBase> args; args.push_back(Variant<ustring>::create(objpath)); args.push_back(Variant<ustring>::create("NativePath")); VariantContainerBase data = attrs->call_sync("Get", VariantContainerBase::create_tuple(args)); LOG("return type: %s", data.get_type_string().c_str()); } 对象包含VariantContainerBase签名。这意味着该对象是“变体”,因此我无法将其转换为任何内容。

对属性的反省表明(v)包含字符串值。那么为什么NativePath方法返回变体类型的对象呢?我错过了什么吗?任何人都可以告诉我,如何在不使用call_sync()方法且没有NativePath将数据放入我自己的缓冲区的情况下正确阅读get_data()属性?我希望尽可能做到类型安全。

还有一件事。当我使用memcpy方法时,我以编码形式获得data.print(true)属性的正确内容。这意味着引擎知道这是字符串。那么为什么它将其作为变体报告呢?这是一个错误还是一个功能? :P

对不起我的英语,我的困惑,谢谢你的帮助。

1 个答案:

答案 0 :(得分:0)

好的,我有解决方案:这似乎是一个错误,或者至少这是一个我不理解的逻辑。

而不是调用VariantContainerBase的{​​{1}},正确的方法是调用直接的Glib函数get_child(0),就像f.e.这样:

g_variant_get_child()

它会将GVariant *output; g_variant_get_child(data.gobj(), 0, "v", & output); 的变体类型正确设置为output内的变体类型(在我的情况下,它会将v的类型设置为output)。在此之后,当您获得s类型的远程数据时,可以将其转换为s,如下所示:

Variant<ustring>

似乎有效。