在java中运行时将DBus Variant的值转换为正确的类型
Posted
技术标签:
【中文标题】在java中运行时将DBus Variant的值转换为正确的类型【英文标题】:Casting the value of a DBus Variant to the correct type at runtime in java 【发布时间】:2014-05-08 08:07:49 【问题描述】:我一直在为这个问题苦苦挣扎。
我正在使用 DBus 的 DBus-java 绑定处理属性设置。当调用 Set 时,要设置的值被包装在一个 org.freedesktop.types.Variant 对象中,我必须从中提取它。通常,如果数据是原始数据,我可以在 Set 参数中使用泛型,并且绑定会在调用 Set 方法之前进行类型转换。
但是,我尝试使用 org.freedesktop.types.DBusStructType 进行设置,这是一种复杂类型,需要手动解包。到目前为止,我已经到了可以从变体中提取类型的地步,但我无法将包装在 Variant 中的值转换为 DBusStructType,即使它被明确标识为 DBusStructType
以下代码在使用来自 python dbus 测试的 DBus.Struct 调用时会引发 ClassCastException: Cannot cast [Ljava.lang.Object; to org.freedesktop.dbus.types.DBusStructType
。我检查了变体签名是否正确打包,但我找不到将 Variant.getValue() 返回的对象转换为 Variant.getType() 指定的类型并访问结构字段的方法。
public void Set(String interface_name, String property_name, Variant new_value) throws Exception
Type t = new_value.getType();
Object s = new_value.getValue();
t.getClass().cast(s);
System.out.println("Object cast to "+s.getClass().getName());
任何指针都将不胜感激,我已经开始深入研究反思,因为我还是新手,但我可能缺少一些东西。
【问题讨论】:
【参考方案1】:我根本没有使用过类型接口,但看起来唯一已知的实现类是 Class。我建议将它作为一个类进行转换,然后调用 cast。
public void Set(String interface_name, String property_name, Variant new_value) throws Exception
Type t = new_value.getType();
Object s = new_value.getValue();
((Class)t).cast(s);
System.out.println("Object cast to "+s.getClass().getName());
希望这会有所帮助。
【讨论】:
谢谢,可悲的是它不起作用,但更仔细地查看我的类型,我终于明白了:我必须将 getValue() 结果转换为正确的类型,在 DBusStructType 的情况下对应一个 Object[]。【参考方案2】:getValue() 返回的 Object 需要转换为与 Dbus 类型对应的正确类型。通过深入研究 DBusStructType 和 DBusStruct,Variant.getValue() 返回的 Object 在 DBusStruct 的情况下是一个 Object[]。这是工作代码:
public void Set(String interface_name, String property_name, Variant new_value) throws Exception
Object[] s = (Object[])new_value.getValue();
System.out.println("client ID: " + (Long)s[0] + ", string: " + (String) s[1]);
输出:
client ID: 0, string: Hello, this is data.
请注意,在转换 Object[] 之前,我会在最终实现中对 Variant 进行签名检查,否则它将因其他 DBus 类型而失败。
【讨论】:
以上是关于在java中运行时将DBus Variant的值转换为正确的类型的主要内容,如果未能解决你的问题,请参考以下文章
当 Java APM 代理在 Docker 中运行时,如何将 Java APM 代理连接到 APM 服务器?
dbus Variant:如何在 Python 中保留布尔数据类型?
使用 glib 和 dbus dbus_g_value_build_g_variant 构建 Maliit 时出错
在适用于 Linux 的 Oracle Agile 9.3.0.2 中运行时 Apache POI 中的 java.lang.IncompatibleClassChangeError