2012-01-23 35 views
0

我遇到了一個簡單的D-Bus概念問題。我正在使用Glibmm D-Bus綁定(Gio :: DBus命名空間)來訪問UDisks接口。我想讀取系統上找到的每個硬盤的一些屬性,所以首先我需要枚舉UDisks是報告的所有磁盤,這樣的:D-Bus,UDisks和Glibmm的綁定

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)對象,它基本上是:「對象路徑數組的一個結構」。從文檔中我看到,「對象路徑」類型的處理方式與「字符串」類型相同,這就是爲什麼在get_child(0)期間創建的非類型化的VariantBase允許自己被轉換爲Variant<ustring>對象。使用這個參數化的Variant,通過使用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)方法時,我以編碼形式得到NativePath屬性的正確內容。這意味着引擎知道這是一個字符串。那麼爲什麼它將它報告爲變體?它是一個錯誤還是一個功能? :P

對不起,我的英語,我的困惑,並感謝您的任何幫助。

回答

0

好的,我有解決方案:這似乎是一個錯誤,或者至少是我不明白的邏輯。

而不是調用VariantContainerBaseget_child(0),正確的方法是調用直接glib函數g_variant_get_child(),如f.e.這樣的:

GVariant *output; 
g_variant_get_child(data.gobj(), 0, "v", & output); 

將正確的output的變量類型設置爲一個這裏面v(在我的情況下,它會的output類型設置爲s)。在此之後,當你在s類型得到遠程數據,你可以將其轉換爲Variant<ustring>這樣的:

Variant<Glib::ustring> item(output); 
Glib::ustring text = item.get(); 

看來工作。