You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

成功获取字符串后,无法用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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.28 03:17:03