【问题标题】:How do i read a dbus array of dicts with the c api sd-bus?如何使用 c api sd-bus 读取 dbus 字典数组?
【发布时间】:2022-10-05 12:08:09
【问题描述】:

我正在尝试使用 sd-bus 读取一个看起来像这样的 a{sv} 的 dbus 数据结构,但是当我使用下面的代码时,我只能读取 8 个字典之一。

#include <stdio.h>
#include <stdlib.h>
#include <systemd/sd-bus.h>


int main()
{
sd_bus* bus = NULL;
sd_bus_error err = SD_BUS_ERROR_NULL;
sd_bus_message *msg = NULL;
char const *sign;
int signi=0;
int error;


sd_bus_default_user(&bus);

sd_bus_get_property(bus,
"org.mpris.MediaPlayer2.plasma-browser-integration",
"/org/mpris/MediaPlayer2",
"org.mpris.MediaPlayer2.Player",
"Metadata",
&err,&msg,"a{sv}");
sign=sd_bus_message_get_signature(msg,signi);

error=sd_bus_message_enter_container(msg,SD_BUS_TYPE_ARRAY,"{sv}");
while(error=sd_bus_message_enter_container(msg,SD_BUS_TYPE_DICT_ENTRY,"sv")>0){

const char *key;

sd_bus_message_read_basic(msg,SD_BUS_TYPE_STRING,&key);
sign=sd_bus_message_get_signature(msg,signi);
printf("returned: %s \n",key);

sd_bus_message_exit_container(msg);


}
sd_bus_message_exit_container(msg);

if(err._need_free!=0){
     printf("%d \n",error);
    printf("returned error: %s\n",err.message);
}else{
    printf("%s",sign);

}
sd_bus_error_free(&err);
sd_bus_unref(bus);

return 0;
}

我在 hotexamples.com 上查找了函数 sd_bus_message_enter_container 并且所有这些似乎都有一个以上循环围绕进入 dict 的函数在我看来,这将循环告诉它具有所有值,但这并没有似乎工作我也尝试将循环与进入数组的函数一起使用但不起作用。另一种尝试的方法是运行一个循环 8 次的 for 循环,之后我尝试寻找其他解决方案,但我看不到任何解决方案。我还使用 freedesktops 网站 (https://www.freedesktop.org/software/systemd/man/sd-bus.html) 上的文档,我让它与 gdbus 一起使用,但据我所知,它已被贬值。为什么这不起作用我不明白。

预先感谢您的帮助。

【问题讨论】:

    标签: c linux dbus


    【解决方案1】:

    我没有意识到我必须读取每个值,否则它会抛出一个错误,如果你不想有一个跳过功能。 这是有效的代码

    #include <stdio.h>
    #include <stdlib.h>
    #include <systemd/sd-bus.h>
    #include <stdbool.h>
    #include <string.h>
    
    int bus_print_property(const char *name, sd_bus_message *property) {
            char type;
            const char *contents;
            int r;
    
    
    
            r = sd_bus_message_peek_type(property, &type, &contents);
            if (r < 0)
                    return r;
    
            switch (type) {
    
            case SD_BUS_TYPE_STRING: {
                    const char *s;
    
                    r = sd_bus_message_read_basic(property, type, &s);
                    if (r < 0)
                            return r;
    
                    printf("%s=%s
    ", name, s);
    
                    return 1;
            }
    
            case SD_BUS_TYPE_BOOLEAN: {
                    bool b;
    
                    r = sd_bus_message_read_basic(property, type, &b);
                    if (r < 0)
                            return r;
    
                    printf("%s
    ", name);
    
                    return 1;
            }
    
            case SD_BUS_TYPE_INT64: {
                    int64_t i64;
    
                    r = sd_bus_message_read_basic(property, type, &i64);
                    if (r < 0)
                        return r;
    
                    printf("%s=%i
    ", name, (int) i64);
                return 1;
            }
    
            case SD_BUS_TYPE_INT32: {
                    int32_t i;
    
                    r = sd_bus_message_read_basic(property, type, &i);
                    if (r < 0)
                            return r;
    
                    printf("%s=%i
    ", name, (int) i);
                    return 1;
            }
    
            case SD_BUS_TYPE_OBJECT_PATH:{
                const char *p;
    
                r = sd_bus_message_read_basic(property, type, &p);
                if (r < 0)
                    return r;
    
                printf("%s=%s
    ", name, p);
    
                return 1;
    
    
            }
    
            case SD_BUS_TYPE_DOUBLE: {
                    double d;
    
                    r = sd_bus_message_read_basic(property, type, &d);
                    if (r < 0)
                            return r;
    
                    printf("%s=%g
    ", name, d);
                    return 1;
            }
    
            case SD_BUS_TYPE_ARRAY:
                    if (strcmp(contents, "s")==0) {
                            bool first = true;
                            const char *str;
    
                            r = sd_bus_message_enter_container(property, SD_BUS_TYPE_ARRAY, contents);
                            if (r < 0)
                                    return r;
    
                            while((r = sd_bus_message_read_basic(property, SD_BUS_TYPE_STRING, &str)) > 0) {
                                    if (first)
                                            printf("%s=", name);
    
                                    printf("%s%s", first ? "" : " ", str);
    
                                    first = false;
                            }
                            if (r < 0)
                                    return r;
    
                            if (first )
                                    printf("%s=", name);
                            if (!first )
                                    puts("");
    
                            r = sd_bus_message_exit_container(property);
                            if (r < 0)
                                    return r;
    
                            return 1;
    
                    } else {
                            printf("array unreadable");
                            return 0;
                    }
    
                    break;
            }
    
            return 0;
    }
    
    int main()
    {
    sd_bus* bus = NULL;
    sd_bus_error err = SD_BUS_ERROR_NULL;
    sd_bus_message *msg = NULL;
    int error;
    
    
    
    sd_bus_default_user(&bus);
    
    sd_bus_get_property(bus,
    "org.mpris.MediaPlayer2.plasma-browser-integration",
    "/org/mpris/MediaPlayer2",
    "org.mpris.MediaPlayer2.Player",
    "Metadata",
    &err,&msg,"a{sv}");
    error = sd_bus_message_enter_container(msg, SD_BUS_TYPE_ARRAY, "{sv}");
            if (error < 0)
                    return error;
    
            while ((error = sd_bus_message_enter_container(msg, SD_BUS_TYPE_DICT_ENTRY, "sv")) > 0) {
                    const char *name;
                    const char *contents;
    
                    error = sd_bus_message_read_basic(msg, SD_BUS_TYPE_STRING, &name);
                    if (error < 0)
                        return error;
    
    
                    error = sd_bus_message_peek_type(msg, NULL, &contents);
                    if (error < 0)
                        return error;
    
                    error = sd_bus_message_enter_container(msg, SD_BUS_TYPE_VARIANT, contents);
                    if (error < 0)
                       return error;
    
                    error = bus_print_property(name, msg);
                    if (error < 0)
                        return error;
                    if (error == 0) {
    
                                            printf("%s=[unprintable]
    ", name);
                                    /* skip what we didn't read */
                                    error = sd_bus_message_skip(msg, contents);
                                    if (error < 0)
                                            return error;
                            }
    
                            error = sd_bus_message_exit_container(msg);
                            if (error < 0)
                                    return error;
    
    
                    error = sd_bus_message_exit_container(msg);
                    if (error < 0)
                            return error;
            }
            if (error < 0)
                    return error;
    
            error = sd_bus_message_exit_container(msg);
            if (error < 0)
                    return error;
    
    
    if(err._need_free!=0){
         printf("%d 
    ",error);
        printf("returned error: %s
    ",err.message);
    }else{
    
    
    }
    sd_bus_error_free(&err);
    sd_bus_unref(bus);
    
    return 0;
    }
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2020-09-08
      • 2017-04-06
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2015-06-30
      • 2020-08-12
      相关资源
      最近更新 更多