2012-01-23 3 views
0

간단한 D 버스 개념에 문제가 있습니다. Glibmm D-Bus 바인딩 (Gio :: DBus 네임 스페이스)을 사용하여 UDisk 인터페이스에 액세스하고 있습니다. 나는 시스템에서 발견 된 모든 하드 디스크의 일부 속성을 읽고 싶은, 그래서 처음 엔 이렇게, UDisks보고 모든 디스크를 열거 할 필요 :이 call_sync()이를 반환하기 때문에, 확인을 작동하는 것 같다D-Bus, UDisk 및 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; 
} 

(ao) 개체를 보유하고있는 VariantContainerBase은 기본적으로 "개체 경로 배열의 한 구조체"입니다. 문서에서 "객체 경로"유형이 "문자열"유형과 같은 방식으로 처리되므로 get_child(0) 중에 작성된 유형이 지정되지 않은 VariantBaseVariant<ustring> 객체에 캐스팅 될 수 있습니다. 이 매개 변수화 된 Variant를 사용하면 var.get()을 사용하여 문자열을 추출하는 것이 간단합니다.

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 속성을) 몇 가지 물건을 읽으려고 서명. 즉, 개체가 "변형"이므로 아무 것도 변형 할 수 없습니다.

속성의 내부 검토 NativePath에는 문자열 값이 있습니다. 그렇다면 call_sync() 메서드가 변형 유형의 객체를 반환하는 이유는 무엇입니까? 내가 놓친 게 있니? 아무도 말해, 메서드를 사용하지 않고 memcpy 데이터를 내 자신의 버퍼에 넣지 않고 어떻게 NativePath 속성을 제대로 읽을 수 있습니까? 가능한 한 유형 안전으로하고 싶습니다.

한 가지 더. data.print(true) 메서드를 사용할 때 NativePath 특성의 적절한 내용이 인코딩 된 형식으로 표시됩니다. 이것은 엔진이 문자열이라는 것을 알고 있음을 의미합니다. 왜 변형으로보고합니까? 버그 또는 기능입니까? : P

죄송합니다. 제 영어는 혼란스럽고 도움이됩니다.

답변

0

좋아요, 해결책이 있습니다. 이것은 버그 인 것 같습니다. 아니면 적어도 내가 이해하지 못하는 논리입니다.

VariantContainerBaseget_child(0)을 호출하는 대신 f.e.와 같은 직접적인 Glib 함수 g_variant_get_child()을 호출하는 것이 적절합니다. 이 :

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

이 제대로 (내 경우는 soutput의 유형을 설정합니다) 내부 v의 하나에 output의 변형 유형을 설정합니다. 당신이 s 유형의 원격 데이터를 얻을 때이 후,이 같은 Variant<ustring>에 전송할 수 있습니다 : 작동하는 것 같다

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

.