C和dbus字典与glib

问题描述:

我目前正在建立一个程序,需要与d-bus接口。我正在使用glib dbus库。我有一个返回DBUS字典类型,像这样的方法:C和dbus字典与glib

array [ 
    dict entry(
    string "Metadata" 
    variant    array [ 
      dict entry(
       string "mpris:artUrl" 
       variant      string "http://open.spotify.com/thumb/05e9ad92c22953e6c778536613605b67faa5a095" 
      ) 
      dict entry(
       string "mpris:length" 
       variant      uint64 238000000 
      ) 

我的问题是,如何在地球上我在我的C程序得到这个?我已经尝试了通常的`dbus_g_proxy_connect_signal'与注册编组没有太多运气!

编辑:我已经添加了一些示例代码(这是不工作,但并编译)

#include <string.h> 
#include <glib.h> 
#include <dbus/dbus.h> 
#include <dbus/dbus-glib.h> 

#define DBUS_SERVICE  "com.spotify.qt" 
#define DBUS_PATH   "/" 
#define DBUS_INTERFACE "org.freedesktop.MediaPlayer2" 

#define DBUS_TYPE_G_STRING_VALUE_HASHTABLE (dbus_g_type_get_map ("GHashTable",  G_TYPE_STRING, G_TYPE_VALUE)) 
//Global bus connection 
DBusGConnection *bus; 
DBusGProxy *proxy; 
//Main gloop 
GMainLoop *loop = NULL; 

//Callback function. 
static void callbackfunc(DBusGProxy *player_proxy, GHashTable *table){ 
GValue *value; 
/* fetch values from hash table */ 
value = (GValue *) g_hash_table_lookup(table, "artist"); 
if (value != NULL && G_VALUE_HOLDS_STRING(value)) { 
    g_print("\nArtist: %s\n",g_value_get_string(value)); 
} 
value = (GValue *) g_hash_table_lookup(table, "album"); 
if (value != NULL && G_VALUE_HOLDS_STRING(value)) { 
    g_print("\nAlbum: %s\n",g_value_get_string(value)); 
} 
value = (GValue *) g_hash_table_lookup(table, "title"); 
if (value != NULL && G_VALUE_HOLDS_STRING(value)) { 
    g_print("\nTitle: %s\n",g_value_get_string(value)); 
} 
} 

int main (int argc, char **argv){ 
GError *error = NULL; 
g_type_init(); 

/* Get (on) the bus :p */ 
bus = dbus_g_bus_get (DBUS_BUS_SESSION, &error); 
if (bus == NULL) { 
    g_printerr("Failed to open connection to bus: %s", error->message); 
    g_error_free(error); 
    return -1; 
} 

/* Create a proxy object for the bus driver */ 
proxy = dbus_g_proxy_new_for_name (bus, 
            DBUS_SERVICE, 
            DBUS_PATH, 
            DBUS_INTERFACE); 

if (!proxy) { 
    g_printerr("Couldn't connect: %s", error->message); 
    g_error_free(error); 
    return -1; 
} 

/* Create the main loop instance */ 
loop = g_main_loop_new (NULL, FALSE); 

dbus_g_proxy_add_signal(proxy, "GetMetadata", 
     DBUS_TYPE_G_STRING_VALUE_HASHTABLE, G_TYPE_INVALID); 

dbus_g_proxy_connect_signal(proxy, "GetMetadata", 
           G_CALLBACK(callbackfunc), NULL, NULL); 

g_print("Going into main function\n"); 
/* Main loop */ 
g_main_loop_run (loop); 

return 0; 
} 
+0

在新代码中,您确实应该使用[GIO](http://developer.gnome.org/gio/stable/index.html)而不是glib-dbus,这已被弃用... – 2012-01-18 17:36:09

+0

哦,我看到, 非常感谢 :) – 0xFFFF 2012-01-21 13:16:02

我要去端口我的代码使用GIO而不是能说会道-dbus的,我怎么曾经设法得到它与巧舌如簧,DBUS使用这方面的工作:

if (dbus_g_proxy_call(p_proxy_md, "GetMetadata", NULL, G_TYPE_INVALID, DBUS_TYPE_G_STRING_VALUE_HASHTABLE, &table, G_TYPE_INVALID)) { 
value = (GValue *) g_hash_table_lookup(table, "xesam:title"); 
sprintf(currentTrack.trackname,"%s",g_value_get_string(value)); 
value = (GValue *) g_hash_table_lookup(table, "xesam:album"); 
sprintf(currentTrack.album,"%s",g_value_get_string(value)); 
tmp = g_hash_table_lookup(table, "xesam:artist"); 
if (tmp != NULL) 
    { 
    GStrv strv = g_value_get_boxed(g_hash_table_lookup(table, "xesam:artist")); 
    sprintf(currentTrack.artist,"%s",*strv); 

    } 
} 
sprintf(notifybody,"By %s on %s",currentTrack.artist,currentTrack.album); 
music_noti = notify_notification_new(currentTrack.trackname,notifybody, NULL); 
notify_notification_set_timeout(music_noti,1500); 
notify_notification_set_icon_from_pixbuf(music_noti, notifyicon); 
notify_notification_show(music_noti, NULL); 
notify_uninit(); 
} 

不使用油滑或任何外部库,我发现在this post概述的最佳途径。

它需要提前知道数据类型的结构,这有点烦人。但是,您可以使用dbus-monitor来查看DBUS先发送的内容。然后你必须为数组的每个级别创建一个迭代器。有关如何使用迭代器,请参见DBUS message documentation