C и dbus словари с glib - PullRequest
       12

C и dbus словари с glib

2 голосов
/ 27 декабря 2011

В настоящее время я создаю программу, которая должна взаимодействовать с шиной 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´ с зарегистрированным маршаллером без особой удачи!

Редактировать: я добавил пример кода (который не работает, но компилируется)

#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 ]

2 голосов
/ 21 января 2012

Я собираюсь портировать свой код для использования 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();
}
0 голосов
/ 10 апреля 2014

Без использования GLIB или какой-либо внешней библиотеки лучший способ, который я нашел, описан в этом посте .

Требуется заранее знать структуру типа данных, что немного раздражает.Однако вы можете использовать dbus-monitor, чтобы увидеть, что DBUS отправляет первым.Затем вы должны сделать итератор для каждого уровня массива.Информацию о том, как использовать итераторы, см. В сообщениях DBUS .

...