使用 glib 的 C 和 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”,但运气不佳!
编辑:我添加了一些示例代码(它不起作用,但可以编译)
#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 技术交流群。

绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(2)
我将移植我的代码以使用 GIO 而不是 glib-dbus,我如何设法让它与 glib-dbus 一起使用:
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:
在不使用 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.