我正在尝试将以下python代码转换为vala
def powerStatusAvailable():
"""
Check if org.freedesktop.UPower is available so that
:py:func:`tools.onBattery` would return the correct power status.
Returns:
bool: ``True`` if :py:func:`tools.onBattery` can report power status
"""
if dbus:
try:
bus = dbus.SystemBus()
proxy = bus.get_object('org.freedesktop.UPower',
'/org/freedesktop/UPower')
return 'OnBattery' in proxy.GetAll('org.freedesktop.UPower',
dbus_interface = 'org.freedesktop.DBus.Properties')
except dbus.exceptions.DBusException:
pass
return False
作为vala的入门者,我很失落。 我不了解对象层次结构。 文档和示例使用Bus类。 还有一个类DBusProxy 我应该使用那个吗? ...它具有方法get_cached_property_names
Bus和DBusProxy有什么区别?
这是我的尝试,但是当然失败了。
using GLib;
// example of a DBus client
[DBus (name = "org.freedesktop.UPower")]
interface UPowerManager : GLib.Object {
public abstract GLib.ObjectPath[] enumerate_devices () throws GLib.DBusError,GLib.IOError;
public abstract GLib.ObjectPath get_display_device () throws GLib.DBusError,GLib.IOError;
public abstract string get_critical_action () throws GLib.DBusError,GLib.IOError;
public abstract string[] get_cached_property_names () throws GLib.DBusError,GLib.IOError;
}
int main (string[] args)
{
UPowerManager upower_manager;
upower_manager = Bus.get_proxy_sync(BusType.SYSTEM,"org.freedesktop.UPower","/org/freedesktop/UPower");
string[] property_names;
property_names = upower_manager.get_cached_property_names();
stdout.printf ("Hello, World!\n");
return 0;
}
但是编译错误
未捕获的错误:GDBus.Error:org.freedesktop.DBus.Error.UnknownMethod:没有这样的方法'GetCachedPropertyNames'
答案 0 :(得分:2)
这是我所做的:
首先,我使用DBus.Introspectable
得到了XML定义:
dbus-send --system --print-reply --type=method_call --dest=org.freedesktop.UPower /org/freedesktop/UPower org.freedesktop.DBus.Introspectable.Introspect
您可以将该命令的结果转储到.xml文件中,但请确保仅包含XML,该文件应如下所示:
<!DOCTYPE node PUBLIC "-//freedesktop//DTD D-BUS Object Introspection 1.0//EN"
"http://www.freedesktop.org/standards/dbus/1.0/introspect.dtd">
<!-- GDBus 2.58.3 -->
<node>
<interface name="org.freedesktop.DBus.Properties">
… and so on
</node>
下一步是使用vala-dbus-binding-tool
创建接口,您可以从https://github.com/freesmartphone/vala-dbus-binding-tool那里获得
vala-dbus-binding-tool -v
这将生成一些vala文件,其中之一包含org.freedesktop.UPower
的正确接口。
剩下的就是使用它,这非常简单,这是一个简单的示例:
[DBus (name = "org.freedesktop.UPower", timeout = 120000)]
public interface UPower : GLib.Object {
[DBus (name = "EnumerateDevices")]
public abstract async GLib.ObjectPath[] enumerate_devices() throws DBusError, IOError;
[DBus (name = "GetDisplayDevice")]
public abstract async GLib.ObjectPath get_display_device() throws DBusError, IOError;
[DBus (name = "GetCriticalAction")]
public abstract async string get_critical_action() throws DBusError, IOError;
[DBus (name = "DeviceAdded")]
public signal void device_added(GLib.ObjectPath device);
[DBus (name = "DeviceRemoved")]
public signal void device_removed(GLib.ObjectPath device);
[DBus (name = "DaemonVersion")]
public abstract string daemon_version { owned get; }
[DBus (name = "OnBattery")]
public abstract bool on_battery { get; }
[DBus (name = "LidIsClosed")]
public abstract bool lid_is_closed { get; }
[DBus (name = "LidIsPresent")]
public abstract bool lid_is_present { get; }
}
int main (string[] args)
{
UPower upower;
upower = Bus.get_proxy_sync(BusType.SYSTEM, "org.freedesktop.UPower",
"/org/freedesktop/UPower");
if (upower.on_battery) {
stdout.printf ("System is running on battery\n");
}
else {
stdout.printf ("System is running on line current\n");
}
return 0;
}
关于您有关GLib.Bus与GLib.DBusProxy的问题。
我不是专家,但是如果您查看生成的C代码(您可以使用valac -C
获得),
static gboolean
upower_dbus_proxy_get_on_battery (UPower* self)
{
GVariant *_inner_reply;
gboolean _result;
_inner_reply = g_dbus_proxy_get_cached_property ((GDBusProxy *) self, "OnBattery");
if (!_inner_reply) {
GVariant *_arguments;
GVariant *_reply;
GVariantBuilder _arguments_builder;
g_variant_builder_init (&_arguments_builder, G_VARIANT_TYPE_TUPLE);
g_variant_builder_add_value (&_arguments_builder, g_variant_new_string ("org.freedesktop.UPower"));
g_variant_builder_add_value (&_arguments_builder, g_variant_new_string ("OnBattery"));
_arguments = g_variant_builder_end (&_arguments_builder);
_reply = g_dbus_proxy_call_sync ((GDBusProxy *) self, "org.freedesktop.DBus.Properties.Get", _arguments$
if (!_reply) {
gboolean _tmp8_ = FALSE;
return _tmp8_;
}
g_variant_get (_reply, "(v)", &_inner_reply);
g_variant_unref (_reply);
}
_result = g_variant_get_boolean (_inner_reply);
g_variant_unref (_inner_reply);
return _result;
}
DBus标记接口的高级功能将自动在内部DBusProxy对象上调用其方法,而无需自己在Vala中编写该低级代码。