在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 用 java 发送 sv?

从 Eclipse 中运行时,JSTL 不起作用

dbus Variant:如何在 Python 中保留布尔数据类型?

使用 glib 和 dbus dbus_g_value_build_g_variant 构建 Maliit 时出错

在适用于 Linux 的 Oracle Agile 9.3.0.2 中运行时 Apache POI 中的 java.lang.IncompatibleClassChangeError