带有glib的C和dbus词典

时间:2011-12-27 16:52:08

标签: c dictionary glib dbus

我目前正在构建一个需要与d-bus接口的程序。我正在使用glib dbus库。我有一个返回dbus字典类型的方法,如下所示:

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'与一个注册的marshaller没有太多运气!

编辑:我添加了一些示例代码(哪些不起作用,但确实编译)

#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;
} 

2 个答案:

答案 0 :(得分:2)

我要将我的代码移植到使用GIO而不是glib-dbus,我做了如何设法使用它来使用glib-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();
}

答案 1 :(得分:0)

在不使用GLIB或任何外部库的情况下,this post概述了我找到的最佳方式。

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