如何将GStrv(string[])类型的GLib.Value转换为GLib.Variant



在以下示例中,一个类属性的类型为Gstrv。使用ObjectClass.list_properties()可以查询所有属性的Paramspec,使用get_property()可以将所有属性请求为GLib.Value。如何访问类型为GStrv的Value并将其转换为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 ("%sn", spec.get_name ());
Value property_value = Value(spec.value_type);
print ("%sn", 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

使用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 ("%sn", spec.get_name ());
Value property_value = Value(spec.value_type);
print ("%sn", 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("%sn", first_gstrv_property_as_variant(foo).print(true));
foo.bar.set("baz", 42);
print("%sn", first_gstrv_property_as_variant(foo).print(true));
foo.bar.set("zot", 3);
print("%sn", 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()意味着字符串数组被视为以null结尾。在g_variant_new_strv()内部,g_strv_length()函数用于确定长度。

希望有一天它对其他人有用。:-(

最新更新