Как преобразовать GLib.Value типа GStrv (string []) в GLib.Variant - PullRequest
0 голосов
/ 19 апреля 2020

В следующем примере одно свойство класса имеет тип Gstrv. С ObjectClass.list_properties() можно запросить Paramspec всех свойств, а с get_property() все свойства могут быть запрошены как GLib.Value. Как получить доступ к значению типа GStrv и преобразовать его в GLib.Variant?

Моя версия GLib немного устарела, поэтому у меня пока нет функции GLib.Value.to_variant() :(.

public class Foo: GLib.Object {
    public GLib.HashTable<string, int32> bar;

    public Foo() {

        bar = new GLib.HashTable<string, int32>(str_hash, str_equal);

    }

    public string[] bar_keys { owned get { return bar.get_keys_as_array(); } }
}

int main() {
    var foo = new Foo();
    Type type = foo.get_type();
    ObjectClass ocl = (ObjectClass) type.class_ref ();
    foreach (ParamSpec spec in ocl.list_properties ()) {
        print ("%s\n", spec.get_name ());
        Value property_value = Value(spec.value_type);
        print ("%s\n", property_value.type_name ());
        foo.get_property(spec.name, ref property_value);
        // next: convert GLib.Value -> GLib.Variant :(
    }
    foo.bar.set("baz", 42);
    return 0;
}

Вывод:

bar-keys
GStrv

1 Ответ

1 голос
/ 23 апреля 2020

Использование GLib.Value.get_boxed() похоже работает.

Пример:

// compile simply with: valac valacode.vala
public class Foo: GLib.Object {
    public GLib.HashTable<string, int32> bar;

    public Foo() {

        bar = new GLib.HashTable<string, int32>(str_hash, str_equal);

    }

    public string[] bar_keys { owned get { return bar.get_keys_as_array(); } }
}

public Variant first_gstrv_property_as_variant(Object obj)
{
        Type class_type = obj.get_type();
        ObjectClass ocl = (ObjectClass) class_type.class_ref ();
        foreach (ParamSpec spec in ocl.list_properties ()) {
                print ("%s\n", spec.get_name ());
                Value property_value = Value(spec.value_type);
                print ("%s\n", property_value.type_name ());
                obj.get_property(spec.name, ref property_value);
                // next: convert GLib.Value -> GLib.Variant
                if(property_value.type_name () == "GStrv") {
                        return new GLib.Variant.strv((string[])property_value.get_boxed());
                }
        }
        return new GLib.Variant("s", "No property of type GStrv found");

}

int main() {
        var foo = new Foo();
        print("%s\n", first_gstrv_property_as_variant(foo).print(true));

        foo.bar.set("baz", 42);
        print("%s\n", first_gstrv_property_as_variant(foo).print(true));

        foo.bar.set("zot", 3);
        print("%s\n", first_gstrv_property_as_variant(foo).print(true));
        return 0;
}

Вывод:

bar-keys
GStrv
@as []
bar-keys
GStrv
['baz']
bar-keys
GStrv
['baz', 'zot']

В сгенерированном c -коде это выглядит следующим образом:

_tmp18_ = g_value_get_boxed (&property_value);
_tmp19_ = g_variant_new_strv ((gchar**) _tmp18_, -1);

Передача -1 в качестве длины g_variant_new_strv() означает, что строковый массив считается завершенным нулем. Внутри g_variant_new_strv() для определения длины используется функция g_strv_length().

Надеюсь, она когда-нибудь будет полезна кому-то еще. : -)

...