使用 glib 的 C 和 dbus 字典

发布于 2024-12-22 23:17:00 字数 2817 浏览 4 评论 0原文

我目前正在构建一个需要与 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;
} 

I'm currently building a program which needs to interface with the d-bus. I'm using the glib dbus library. I have a method that returns a dbus dictionary type, like this:

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
           )

My question is, how on earth do I get this in my C program? I've tried the usual `dbus_g_proxy_connect_signal´ with a registered marshaller without much luck!

Edit: I've added some sample code (Which is not working, but does compile)

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

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

醉殇 2024-12-29 23:17:00

我将移植我的代码以使用 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();
}

I'm going to port my code to use GIO rather than glib-dbus, I did how ever manage to get it working with glib-dbus using this:

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();
}
瀟灑尐姊 2024-12-29 23:17:00

在不使用 GLIB 或任何外部库的情况下,我发现的最佳方法在 这篇文章

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

Without using GLIB or any external library, the best way I've found is outlined in this post.

It requires knowing the structure of the datatype ahead of time, which is a bit annoying. However, you can use dbus-monitor to see what DBUS is sending first. Then you have to make an iterator for each level of the array. See the DBUS message documentation for how to use the iterators.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文