Вот что я сделал:
Сначала я получил определение XML, используя DBus.Introspectable
:
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 (который вы можете получить с помощью * 1023)*):
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.