成功获取字符串后,无法用sd_bus_message_read()解析字典响应
问题:解析Bluez MediaPlayer1的Track属性失败
背景
我尝试通过org.bluez服务下路径为/org/bluez/hci0/dev_3C_19_5E_F9_26_60/player0的org.bluez.MediaPlayer1接口,从已连接的蓝牙设备中获取曲目详情。目前已成功通过Status属性获取当前播放曲目的状态,代码如下:
#include <stdio.h> #include <stdlib.h> #include <string.h> #include <stdbool.h> #include <systemd/sd-bus.h> int main(int argc, char *argv[]) { sd_bus_error error = SD_BUS_ERROR_NULL; sd_bus_message *m = NULL; sd_bus *bus = NULL; int r; const char *path = NULL; /* Connect to the system bus */ r = sd_bus_open_system(&bus); if (r < 0) { fprintf(stderr, "Failed to connect to system bus: %s\n", strerror(-r)); goto finish; } printf("Connected to system bus\n"); /* Get the property value */ r = sd_bus_get_property(bus, "org.bluez", /* service to contact */ "/org/bluez/hci0/dev_3C_19_5E_F9_26_60/player0", /* object path */ "org.bluez.MediaPlayer1",/* interface name */ "Status", /* property name */ &error, /* object to return error in */ &m, /* return message on success */ "s" /* type */ ); if (r < 0) { fprintf(stderr, "Failed to get property: %s\n", error.message); goto finish; } printf("Successfully got property\n"); /* Parse the response message */ r = sd_bus_message_read(m, "s", &path); if (r < 0) { fprintf(stderr, "Failed to parse response message: %s\n", strerror(-r)); goto finish; } printf("Successfully parsed response message\n"); if (path != NULL) printf("Track status is: %s\n", path); else printf("Track status not found\n"); finish: sd_bus_error_free(&error); sd_bus_message_unref(m); sd_bus_unref(bus); return 0; }
尝试获取Track属性的错误代码
随后我扩展代码,试图通过Track属性获取曲目名称、时长、艺术家名称等信息,但解析环节失败,相关代码如下:
#include <stdio.h> #include <stdlib.h> #include <string.h> #include <stdbool.h> #include <systemd/sd-bus.h> int main(int argc, char *argv[]) { sd_bus_error error = SD_BUS_ERROR_NULL; sd_bus_message *m = NULL; sd_bus *bus = NULL; int r; const char *title = NULL; uint32_t track_number = 0; uint32_t num_tracks = 0; uint32_t duration = 0; const char *album = NULL; const char *artist = NULL; const char *genre = NULL; /* Connect to the system bus */ r = sd_bus_open_system(&bus); if (r < 0) { fprintf(stderr, "Failed to connect to system bus: %s\n", strerror(-r)); goto finish; } printf("Connected to system bus\n"); /* Get the property value */ r = sd_bus_get_property(bus, "org.bluez", /* service to contact */ "/org/bluez/hci0/dev_3C_19_5E_F9_26_60/player0", /* object path */ "org.bluez.MediaPlayer1",/* interface name */ "Track", /* property name */ &error, /* object to return error in */ &m, /* return message on success */ "a{sv}" /* type */ ); if (r < 0) { fprintf(stderr, "Failed to get property: %s\n", error.message); goto finish; } printf("Successfully got property\n"); /* Parse the response message */ const char *s1, *s2, *s3, *s4, *s5, *s6, *s7; r = sd_bus_message_read(m, "a{sv}", 7, &s1, &title, &s2, &track_number, &s3, &num_tracks, &s4, &duration, &s5, &album, &s6, &artist, &s7, &genre); if (r < 0) { fprintf(stderr, "Failed to parse response message: %s\n", strerror(-r)); goto finish; } printf("Successfully parsed response message\n"); printf("Title: %s\n", title); printf("Track Number: %u\n", track_number); printf("Number of Tracks: %u\n", num_tracks); printf("Duration: %u milliseconds\n", duration); printf("Album: %s\n", album); printf("Artist: %s\n", artist); printf("Genre: %s\n", genre); finish: sd_bus_error_free(&error); sd_bus_message_unref(m); sd_bus_unref(bus); return 0; }
busctl命令及输出
执行以下命令验证Track属性的内容:
busctl get-property org.bluez /org/bluez/hci0/dev_3C_19_5E_F9_26_60/player0 org.bluez.MediaPlayer1 Track
得到的响应包含7组{string => variant}键值对:
a{sv} 7 "Title" s "Tere Naina" "TrackNumber" u 1 "NumberOfTracks" u 1 "Duration" u 278546 "Album" s "My Name Is Khan (Original Motion Picture Soundtrack)" "Artist" s "From Smart Shuffle \342\200\242 Shankar-Ehsaan-Loy, Shafqat Amanat Ali" "Genre" s ""
我查阅了sd_bus_message_read()的文档及相关示例,但未能找到问题所在,请问这段解析Track属性的代码哪里出错了?
内容的提问来源于stack exchange,提问作者its_me_mak
相关产品推荐
相关产品推荐

